Skip to content

Commit

Permalink
Add netstandard2.0 support and increment version.
Browse files Browse the repository at this point in the history
  • Loading branch information
mikernet committed Apr 25, 2021
1 parent 64aa4f1 commit 0088cfb
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 25 deletions.
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ This package is part of our **Singulink Libraries** collection. Visit https://gi

The package is available on NuGet - simply install the `Singulink.Numerics.BigDecimal` package.

**Supported Runtimes**: Anywhere .NET Standard 2.1+ is supported, including:
- .NET Core 3.0+
- Mono 6.4+
- Xamarin.iOS 12.16+
- Xamarin.Android 10.0+
**Supported Runtimes**: Anywhere .NET Standard 2.0+ is supported, including:
- .NET Core 2.0+
- .NET Framework 4.6.1+
- Mono 5.4+
- Xamarin.iOS 10.14+
- Xamarin.Android 8.0+

The package multitargets .NET Standard 2.1 to offer higher performance string conversions on runtimes that support it.

## Further Reading

Expand Down
1 change: 1 addition & 0 deletions Source/Singulink.Numerics.BigDecimal.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
Directory.Build.props = Directory.Build.props
..\README.md = ..\README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Singulink.Numerics.BigDecimal", "Singulink.Numerics.BigDecimal\Singulink.Numerics.BigDecimal.csproj", "{F97DD23B-BDDE-4D18-A38D-6D34AF87A7BF}"
Expand Down
65 changes: 47 additions & 18 deletions Source/Singulink.Numerics.BigDecimal/BigDecimal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -714,8 +714,8 @@ bool TryParseParenthesis(ref ReadOnlySpan<char> s)

bool TryParseStart(ref ReadOnlySpan<char> s)
{
while (s.Length > 0 && !char.IsDigit(s[0]) && !s.StartsWith(formatInfo.NumberDecimalSeparator, cmp)) {
if (allowCurrencySymbol && s.StartsWith(formatInfo.CurrencySymbol, cmp)) {
while (s.Length > 0 && !char.IsDigit(s[0]) && !s.StartsWith(formatInfo.NumberDecimalSeparator.AsSpan(), cmp)) {
if (allowCurrencySymbol && s.StartsWith(formatInfo.CurrencySymbol.AsSpan(), cmp)) {
if (currency)
return false;

Expand All @@ -740,12 +740,12 @@ bool TryParseStart(ref ReadOnlySpan<char> s)

bool StartsWithSign(ReadOnlySpan<char> s, out int sign, out int signLength)
{
if (s.StartsWith(formatInfo.PositiveSign, cmp)) {
if (s.StartsWith(formatInfo.PositiveSign.AsSpan(), cmp)) {
sign = 1;
signLength = formatInfo.PositiveSign.Length;
return true;
}
else if (s.StartsWith(formatInfo.NegativeSign, cmp)) {
else if (s.StartsWith(formatInfo.NegativeSign.AsSpan(), cmp)) {
sign = -1;
signLength = formatInfo.NegativeSign.Length;
return true;
Expand All @@ -759,8 +759,8 @@ bool StartsWithSign(ReadOnlySpan<char> s, out int sign, out int signLength)

bool TryParseEnd(ref ReadOnlySpan<char> s)
{
while (s.Length > 0 && !char.IsDigit(s[^1]) && !s.EndsWith(formatInfo.NumberDecimalSeparator, cmp)) {
if (allowCurrencySymbol && s.EndsWith(formatInfo.CurrencySymbol, cmp)) {
while (s.Length > 0 && !char.IsDigit(s[^1]) && !s.EndsWith(formatInfo.NumberDecimalSeparator.AsSpan(), cmp)) {
if (allowCurrencySymbol && s.EndsWith(formatInfo.CurrencySymbol.AsSpan(), cmp)) {
if (currency)
return false;

Expand All @@ -785,12 +785,12 @@ bool TryParseEnd(ref ReadOnlySpan<char> s)

bool EndsWithSign(ReadOnlySpan<char> s, out int sign, out int signLength)
{
if (s.EndsWith(formatInfo.PositiveSign, cmp)) {
if (s.EndsWith(formatInfo.PositiveSign.AsSpan(), cmp)) {
sign = 1;
signLength = formatInfo.PositiveSign.Length;
return true;
}
else if (s.EndsWith(formatInfo.NegativeSign, cmp)) {
else if (s.EndsWith(formatInfo.NegativeSign.AsSpan(), cmp)) {
sign = -1;
signLength = formatInfo.NegativeSign.Length;
return true;
Expand All @@ -810,7 +810,11 @@ bool TryParseExponent(ref ReadOnlySpan<char> s, out int result)
if (index >= 0) {
var e = s[(index + 1)..];
s = s[..index];
#if NETSTANDARD2_0
return int.TryParse(e.ToString(), NumberStyles.AllowLeadingSign, formatProvider, out result);
#else
return int.TryParse(e, NumberStyles.AllowLeadingSign, formatProvider, out result);
#endif
}
}

Expand All @@ -835,7 +839,11 @@ bool TryParseFractional(ref ReadOnlySpan<char> s, out BigDecimal? result)
int exponent = -f.Length;
f = f.TrimStart('0');

#if NETSTANDARD2_0
if (!BigInteger.TryParse(f.ToString(), NumberStyles.None, formatProvider, out var mantissa)) {
#else
if (!BigInteger.TryParse(f, NumberStyles.None, formatProvider, out var mantissa)) {
#endif
result = null;
return false;
}
Expand All @@ -846,7 +854,7 @@ bool TryParseFractional(ref ReadOnlySpan<char> s, out BigDecimal? result)
bool SplitFractional(ref ReadOnlySpan<char> s, out ReadOnlySpan<char> f)
{
string decimalSeparator = currency ? formatInfo.CurrencyDecimalSeparator : formatInfo.NumberDecimalSeparator;
int decimalIndex = s.IndexOf(decimalSeparator, cmp);
int decimalIndex = s.IndexOf(decimalSeparator.AsSpan(), cmp);

if (decimalIndex >= 0) {
f = s[(decimalIndex + decimalSeparator.Length)..];
Expand Down Expand Up @@ -880,7 +888,11 @@ bool TryParseWhole(ReadOnlySpan<char> s, out BigDecimal? result)

var (wholeStyle, wholeFormatInfo) = GetWholeStyleAndInfo();

#if NETSTANDARD2_0
if (!BigInteger.TryParse(s.ToString(), wholeStyle, wholeFormatInfo, out var mantissa)) {
#else
if (!BigInteger.TryParse(s, wholeStyle, wholeFormatInfo, out var mantissa)) {
#endif
result = null;
return false;
}
Expand Down Expand Up @@ -998,7 +1010,11 @@ public string ToString(string? format, IFormatProvider? formatProvider = null)
formatSpecifier = char.ToUpperInvariant(format[0]);

if (format.Length > 1) {
#if NETSTANDARD2_0
if (int.TryParse(format[1..], NumberStyles.None, CultureInfo.InvariantCulture, out int ps))
#else
if (int.TryParse(format.AsSpan()[1..], NumberStyles.None, CultureInfo.InvariantCulture, out int ps))
#endif
precisionSpecifier = ps;
else
throw new FormatException($"Invalid precision specifier: '{format[1..]}'");
Expand Down Expand Up @@ -1098,14 +1114,19 @@ string GetExponentialString(BigDecimal value, int? precisionSpecifier)

int eIndex = result.LastIndexOf("E", StringComparison.Ordinal);

int exponent = int.Parse(result.AsSpan()[(eIndex + 1)..], NumberStyles.AllowLeadingSign, formatInfo) + value._exponent;
#if NETSTANDARD2_0
string exponentString = result[(eIndex + 1)..];
#else
var exponentString = result.AsSpan()[(eIndex + 1)..];
#endif
int exponent = int.Parse(exponentString, NumberStyles.AllowLeadingSign, formatInfo) + value._exponent;
var mantissa = result.AsSpan()[..(eIndex + 1)];
string absExponentString = Math.Abs(exponent).ToString(formatInfo);

if (exponent > 0)
return StringHelper.Concat(mantissa, formatInfo.PositiveSign, absExponentString);
return StringHelper.Concat(mantissa, formatInfo.PositiveSign.AsSpan(), absExponentString.AsSpan());

return StringHelper.Concat(mantissa, formatInfo.NegativeSign, absExponentString);
return StringHelper.Concat(mantissa, formatInfo.NegativeSign.AsSpan(), absExponentString.AsSpan());
}

string GetDecimalString(BigDecimal value, string wholePartFormat, int? fixedDecimalPlaces)
Expand Down Expand Up @@ -1141,12 +1162,20 @@ string GetDecimalString(BigDecimal value, string wholePartFormat, int? fixedDeci
string decimalSeparator = wholePartFormat[0] == 'C' ? formatInfo.CurrencyDecimalSeparator : formatInfo.NumberDecimalSeparator;

var sb = new StringBuilder(wholeString.Length + decimalSeparator.Length + decimalLeadingZeros + decimalString.Length);
#if NETSTANDARD2_0
sb.Append(wholeString[..insertPoint]);
#else
sb.Append(wholeString.AsSpan()[..insertPoint]);
#endif
sb.Append(decimalSeparator);
sb.Append('0', decimalLeadingZeros);
sb.Append(decimalString);
sb.Append('0', decimalTrailingZeros);
sb.Append(wholeString.AsSpan()[insertPoint..]);
#if NETSTANDARD2_0
sb.Append(wholeString[insertPoint..]);
#else
sb.Append(wholeString[insertPoint..]);
#endif

return sb.ToString();
}
Expand Down Expand Up @@ -1187,9 +1216,9 @@ string GetIntegerString(BigDecimal value, string format)
};
}

#endregion
#endregion

#region Equality and Comparison Methods
#region Equality and Comparison Methods

/// <summary>
/// Compares this to another <see cref="BigDecimal"/>.
Expand All @@ -1214,9 +1243,9 @@ public int CompareTo(BigDecimal other)
/// </summary>
public override int GetHashCode() => HashCode.Combine(_mantissa, _exponent);

#endregion
#endregion

#region Helper Methods
#region Helper Methods

// Moved this to a non-local method for docfx. See: https://github.com/dotnet/docfx/issues/7055

Expand All @@ -1239,6 +1268,6 @@ private static BigInteger AlignMantissa(BigDecimal value, BigDecimal reference)
return value._mantissa * BigIntegerPow10.Get(value._exponent - reference._exponent);
}

#endregion
#endregion
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
<RootNamespace>Singulink.Numerics</RootNamespace>
<Version>1.0.0</Version>
<Version>1.0.1</Version>
<Authors>Singulink</Authors>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Copyright>© Singulink. All rights reserved.</Copyright>
Expand Down Expand Up @@ -34,8 +34,11 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="IndexRange" Version="1.0.0" />
<PackageReference Include="Microsoft.Bcl.HashCode" Version="1.1.1" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="all" />
<PackageReference Include="Singulink.Numerics.BigIntegerExtensions" Version="1.1.0" />
<PackageReference Include="System.Memory" Version="4.5.0" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="5.0.0" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ internal static class StringHelper
{
public static unsafe string Concat(ReadOnlySpan<char> s1, ReadOnlySpan<char> s2)
{
#if NETSTANDARD2_0
return s1.ToString() + s2.ToString();
#else
fixed (char* p1 = s1)
fixed (char* p2 = s2) {
var data = (p1: (IntPtr)p1, p2: (IntPtr)p2, length1: s1.Length, length2: s2.Length);
Expand All @@ -16,10 +19,14 @@ public static unsafe string Concat(ReadOnlySpan<char> s1, ReadOnlySpan<char> s2)
new ReadOnlySpan<char>((char*)data.p2, data.length2).CopyTo(span.Slice(data.length1));
});
}
#endif
}

public static unsafe string Concat(ReadOnlySpan<char> s1, ReadOnlySpan<char> s2, ReadOnlySpan<char> s3)
{
#if NETSTANDARD2_0
return s1.ToString() + (s2.ToString() + s3.ToString());
#else
fixed (char* p1 = s1)
fixed (char* p2 = s2)
fixed (char* p3 = s3) {
Expand All @@ -31,6 +38,7 @@ public static unsafe string Concat(ReadOnlySpan<char> s1, ReadOnlySpan<char> s2,
new ReadOnlySpan<char>((char*)data.p3, data.length3).CopyTo(span.Slice(data.length2));
});
}
#endif
}
}
}

0 comments on commit 0088cfb

Please sign in to comment.