Created
January 1, 2018 01:43
-
-
Save mjs3339/f6172e1cdd5b3c005db878ec52035bfa to your computer and use it in GitHub Desktop.
C# Add Functionallity to BigRational AsDecimal AsScientific
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public BigInteger Remainder => Numerator % Denominator; | |
private static ulong HashHold; | |
private static string DecimalString = "0"; | |
private static readonly FNV1a64 _Hasher = new FNV1a64(); | |
public static int DisplayPrecision = 100; | |
public string AsDecimal(bool rounding = false, int toDigits = 100) | |
{ | |
var lh = _Hasher.Hash64(Numerator.ToByteArray()) ^ _Hasher.Hash64(Denominator.ToByteArray()); | |
if (HashHold == lh) return DecimalString; | |
if (DisplayPrecision < 0) | |
{ | |
var ret = new StringBuilder(); | |
ret.Append(Numerator.ToString("R", CultureInfo.InvariantCulture)); | |
ret.Append(_solidus); | |
ret.Append(Denominator.ToString("R", CultureInfo.InvariantCulture)); | |
DecimalString = ret.ToString(); | |
HashHold = lh; | |
return DecimalString; | |
} | |
var rv = new StringBuilder(DisplayPrecision + 1); | |
rv.Append((Numerator - Remainder) / Denominator + "."); | |
var NewNumerator = Remainder * 10; | |
for (var i = 0; i < DisplayPrecision; i++) | |
{ | |
rv.Append((NewNumerator - NewNumerator % Denominator) / Denominator); | |
NewNumerator = NewNumerator % Denominator * 10; | |
} | |
DecimalString = rv.ToString(); | |
if (rounding) | |
{ | |
var dPos = DecimalString.IndexOf(".", StringComparison.Ordinal); | |
if (dPos != -1) | |
{ | |
if (DecimalString.Length + dPos >= toDigits + 1) | |
{ | |
var tempStr = new StringBuilder("0."); | |
DecimalString = DecimalString.Substring(dPos + 1, toDigits + 1); | |
var lastDigit = DecimalString.Substring(DecimalString.Length - 1, 1).ToInt32(); | |
var nextLastDigit = DecimalString.Substring(DecimalString.Length - 2, 1).ToInt32(); | |
tempStr.Append(DecimalString.Substring(0, DecimalString.Length - 2)); | |
tempStr.Append(lastDigit >= 5 ? $"{nextLastDigit + 1}" : $"{nextLastDigit}"); | |
DecimalString = tempStr.ToString(); | |
} | |
} | |
} | |
HashHold = lh; | |
return DecimalString; | |
} | |
public string AsScientific() | |
{ | |
var Offset = 0; | |
AsDecimal(); | |
if (GetWholePart != 0) return DecimalString; | |
var dPos = DecimalString.IndexOf(".", StringComparison.Ordinal); | |
if (dPos == -1) return DecimalString; | |
for (var i = dPos + 1; i < DecimalString.Length; ++i) | |
if (DecimalString[i] == '0') | |
Offset++; | |
else | |
break; | |
if (DecimalString.Length >= Offset + 6) | |
{ | |
var res = new StringBuilder(DecimalString.Substring(Offset + 2, 1)); | |
res.Append("."); | |
res.Append(DecimalString.Substring(Offset + 3)); | |
res.Append("e-"); | |
res.Append($"{Offset + 1}"); | |
return res.ToString(); | |
} | |
else return DecimalString; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment