Skip to content

Commit

Permalink
Init
Browse files Browse the repository at this point in the history
  • Loading branch information
XeroXP committed Jul 11, 2022
0 parents commit 52ae486
Show file tree
Hide file tree
Showing 117 changed files with 46,444 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
**/obj
**/bin
.vs/
packages/
109 changes: 109 additions & 0 deletions DecimalSharp.Core/BigDecimalArgument.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using System.Numerics;

namespace DecimalSharp.Core
{
public struct BigDecimalArgument<TBigDecimal>
{
readonly double _value0;
readonly decimal _value1;
readonly long _value2;
readonly int _value3;
readonly string? _value4;
readonly BigInteger _value5;
readonly TBigDecimal? _value6;
readonly int _index;

BigDecimalArgument(int index, double value0 = default, decimal value1 = default, long value2 = default, int value3 = default, string? value4 = default, BigInteger value5 = default, TBigDecimal? value6 = default)
{
_index = index;
_value0 = value0;
_value1 = value1;
_value2 = value2;
_value3 = value3;
_value4 = value4;
_value5 = value5;
_value6 = value6;
}

public static implicit operator BigDecimalArgument<TBigDecimal>(double t) => new(0, value0: t);
public static implicit operator BigDecimalArgument<TBigDecimal>(decimal t) => new(1, value1: t);
public static implicit operator BigDecimalArgument<TBigDecimal>(long t) => new(2, value2: t);
public static implicit operator BigDecimalArgument<TBigDecimal>(int t) => new(3, value3: t);
public static implicit operator BigDecimalArgument<TBigDecimal>(string? t) => new(4, value4: t);
public static implicit operator BigDecimalArgument<TBigDecimal>(BigInteger t) => new(5, value5: t);
public static implicit operator BigDecimalArgument<TBigDecimal>(TBigDecimal? t) => new(6, value6: t);

public void Switch(Action<double> f0, Action<decimal> f1, Action<long> f2, Action<int> f3, Action<string?> f4, Action<BigInteger> f5, Action<TBigDecimal?> f6)
{
if (_index == 0 && f0 != null)
{
f0(_value0);
return;
}
if (_index == 1 && f1 != null)
{
f1(_value1);
return;
}
if (_index == 2 && f2 != null)
{
f2(_value2);
return;
}
if (_index == 3 && f3 != null)
{
f3(_value3);
return;
}
if (_index == 4 && f4 != null)
{
f4(_value4);
return;
}
if (_index == 5 && f5 != null)
{
f5(_value5);
return;
}
if (_index == 6 && f6 != null)
{
f6(_value6);
return;
}
throw new InvalidOperationException();
}

public TResult Match<TResult>(Func<double, TResult> f0, Func<decimal, TResult> f1, Func<long, TResult> f2, Func<int, TResult> f3, Func<string?, TResult> f4, Func<BigInteger, TResult> f5, Func<TBigDecimal?, TResult> f6)
{
if (_index == 0 && f0 != null)
{
return f0(_value0);
}
if (_index == 1 && f1 != null)
{
return f1(_value1);
}
if (_index == 2 && f2 != null)
{
return f2(_value2);
}
if (_index == 3 && f3 != null)
{
return f3(_value3);
}
if (_index == 4 && f4 != null)
{
return f4(_value4);
}
if (_index == 5 && f5 != null)
{
return f5(_value5);
}
if (_index == 6 && f6 != null)
{
return f6(_value6);
}
throw new InvalidOperationException();
}
}
}
66 changes: 66 additions & 0 deletions DecimalSharp.Core/BigDecimalDivisionFunctions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using DecimalSharp.Core.Extensions;

namespace DecimalSharp.Core
{
public class BigDecimalDivisionFunctions
{
// Assumes non-zero x and k, and hence non-zero result.
protected static int[] multiplyInteger(int[] x, long k, int @base)
{
long temp;
int carry = 0;
long i = x.LongLength;

for (x = x.Slice(); i--.IsTrue();)
{
temp = (long)x[i] * k + carry;
x[i] = (int)(temp % @base) | 0;
carry = (int)(temp / @base) | 0;
}

if (carry.IsTrue()) ArrayExtensions.Unshift(ref x, carry);

return x;
}

protected static int compare(int[] a, int[] b, long aL, long bL)
{
long i;
int r;

if (aL != bL)
{
r = aL > bL ? 1 : -1;
}
else
{
for (i = r = 0; i < aL; i++)
{
if (a[i] != b[i])
{
r = a[i] > b[i] ? 1 : -1;
break;
}
}
}

return r;
}

protected static void subtract(ref int[] a, int[] b, long aL, int @base)
{
var i = 0;

// Subtract b from a.
for (; aL--.IsTrue();)
{
a[aL] -= i;
i = a[aL] < b[aL] ? 1 : 0;
a[aL] = i * @base + a[aL] - b[aL];
}

// Remove leading zeros.
for (; !a[0].IsTrue() && a.LongLength > 1;) ArrayExtensions.Shift(ref a);
}
}
}
12 changes: 12 additions & 0 deletions DecimalSharp.Core/BigDecimalException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace DecimalSharp.Core;

public class BigDecimalException : Exception
{
public static string DecimalError = "[DecimalError] ";
public static string InvalidArgument = DecimalError + "Invalid argument: ";
public static string PrecisionLimitExceeded = DecimalError + "Precision limit exceeded";
public static string ExponentOutOfRange = DecimalError + "Exponent out of range: ";

public BigDecimalException() : base() { }
public BigDecimalException(string message) : base(message) { }
}
35 changes: 35 additions & 0 deletions DecimalSharp.Core/DecimalSharp.Core.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Version>1.0.0</Version>
<Authors>XeroXP</Authors>
<Description>
An arbitrary-precision Decimal type for C#.
Port of [decimal.js](https://github.com/MikeMcl/decimal.js/).
</Description>
<Copyright>Copyright (c) $(Authors) 2022</Copyright>
<PackageProjectUrl>https://github.com/XeroXP/DecimalSharp</PackageProjectUrl>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/XeroXP/DecimalSharp.git</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>decimal, arbitrary-precision, bigdecimal, bignumber, significant-digits, trigonometric-functions, decimal-places</PackageTags>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance>
</PropertyGroup>

<ItemGroup>
<None Include="..\README.md">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
<None Include="..\LICENSE">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>

</Project>
115 changes: 115 additions & 0 deletions DecimalSharp.Core/Extensions/ArrayExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
namespace DecimalSharp.Core.Extensions
{
public static class ArrayExtensions
{
public static void Resize<T>(ref T[] numbers, long newSize)
{
var newNumbers = new T[newSize];
Array.Copy(numbers, 0, newNumbers, 0, Math.Min(numbers.LongLength, newSize));
numbers = newNumbers;
}

public static void Reverse<T>(ref T[] numbers)
{
Array.Reverse(numbers);
/*for (long i = 0; i < numbers.LongLength / 2; i++)
{
var tmp = numbers[i];
numbers[i] = numbers[numbers.LongLength - i - 1];
numbers[numbers.LongLength - i - 1] = tmp;
}*/
}

public static void Pop<T>(ref T[] numbers)
{
Resize(ref numbers, numbers.LongLength - 1);
}

public static void Push<T>(ref T[] numbers, T value)
{
AddElementAt(ref numbers, numbers.LongLength, value);
}

public static T[] Slice<T>(this T[] numbers, long start = 0, long length = 0)
{
if (length == 0) length = numbers.LongLength - start;

if (length > numbers.LongLength - start) length = numbers.LongLength - start;
T[] destfoo = new T[length];
Array.Copy(numbers, start, destfoo, 0, length);
return destfoo;
}

public static T[] StringSlice<T>(this T[] numbers, long start = 0, long end = 0)
{
if (start >= numbers.LongLength) return new T[0];

if (end == 0) end = numbers.LongLength;
if (end > numbers.LongLength) end = numbers.LongLength;

var length = end - start;

T[] destfoo = new T[length];
Array.Copy(numbers, start, destfoo, 0, length);
return destfoo;
}

public static T Shift<T>(ref T[] numbers)
{
if (numbers.LongLength == 0)
return default(T);

T[] cloneArray = (T[])numbers.Clone();
Resize(ref numbers, numbers.LongLength - 1);
for(long i = 1; i < cloneArray.LongLength; i++)
{
numbers[i-1] = cloneArray[i];
}
return cloneArray[0];
}

public static void Unshift<T>(ref T[] numbers, params T[] values)
{
foreach (var value in values.Reverse())
{
AddElementAt(ref numbers, 0, value);
}
}

/// <summary>
/// Add element at nth position in array
/// </summary>
/// <param name="numbers">Source Array</param>
/// <param name="index">Position Number</param>
/// <param name="value">the value to be entered</param>
public static void AddElementAt<T>(ref T[] numbers, long index, T value)
{
//first resize it
Resize(ref numbers, numbers.LongLength + 1);

long orginalLength = numbers.LongLength;
//clone the array
T[] cloneArray = (T[])numbers.Clone();
for (long i = 0; i < orginalLength; i++)
{
if (i == index)
{
//copy element from the position
var element = cloneArray[index];
numbers[index] = value;
if (i + 1 < orginalLength)
numbers[index + 1] = element;
}
else if (i > index)
{
if (i + 1 < orginalLength)
numbers[i + 1] = cloneArray[i];
}
else
{
numbers[i] = cloneArray[i];
}
}
}
}
}
46 changes: 46 additions & 0 deletions DecimalSharp.Core/Extensions/NumberExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System.Globalization;

namespace DecimalSharp.Core.Extensions
{
public static class NumberExtensions
{
public static string ToExponential(this double? value, int? fractionDigits = null)
{
if (!value.HasValue) return "";

return value.Value.ToExponential(fractionDigits);
}

public static string ToExponential(this double value, int? fractionDigits = null)
{
if (!fractionDigits.HasValue)
{
return value.ToString("0.####################e+0", CultureInfo.InvariantCulture);
}

return value.ToString("0." + string.Empty.PadRight(fractionDigits.Value, '0') + "e+0", CultureInfo.InvariantCulture);
}

/*public static bool IsTrue<T>(this T[] value)
{
return value.LongLength != 0;
}*/

public static bool IsTrue<T>(this T[]? value)
{
return value != null && value.LongLength != 0;
}

public static bool IsTrue<T>(this T value) where T : struct
{
return !value.Equals(default(T));
}

public static bool IsTrue<T>(this T? value) where T : struct
{
if (value == null) return false;

return value.HasValue && !value.Value.Equals(default(T));
}
}
}
Loading

0 comments on commit 52ae486

Please sign in to comment.