0

I have a function which works very well for not too big values:

    public BigInteger GetFrom(decimal value)
    {
        var decimalPlaces = 20;
        var factor = (decimal) Math.Pow(10, decimalPlaces);
        return new BigInteger(value * factor);
    }

It transforms correctly:

123m           = 12300000000000000000000
123.123456789m = 12312345678900000000000
0.123m       = 12300000000000000000
0.123456789m = 12345678900000000000
0.123456789012345678902345678901234567890m = 12345678901234567890
1.123456789012345678902345678901234567890m = 112345678901234567890

But trows for something like: 12345678901234567890.12345678901234567890m. Of course because 12345678901234567890.12345678901234567890m * Math.Pow(10, 20) is too big for a decimal, but I don't need this as decimal I need this as BigInteger like the examples before

12345678901234567890.12345678901234567890m = 1234567890123456789012345678901234567890

Buy, I am not sure about what/how is the best way to solve this problem...

Andre
  • 652
  • 2
  • 7
  • 23
  • 3
    Like with using [`BigInteger.Pow`](https://learn.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.pow?view=netframework-4.7.2#System_Numerics_BigInteger_Pow_System_Numerics_BigInteger_System_Int32_)? – Camilo Terevinto Feb 06 '19 at 15:12
  • Well as far I know, if I use this I will lose the decimal places, and I do not want it. The problem is not on the "pow" method the error is here BigInteger(value * factor); the operation at the BigInteger constructor – Andre Feb 06 '19 at 15:17
  • 1
    Move the decimal place over 20 places and use BitInteger. After you complete calculations move decimal place back. It is like 20,000,000 is same as 20M. – jdweng Feb 06 '19 at 15:17
  • @jdweng there is something like MoveDecimalPlaceTo ? – Andre Feb 06 '19 at 15:20
  • What is you input? A string or a number? – jdweng Feb 06 '19 at 15:22
  • A decimal number – Andre Feb 06 '19 at 15:24

2 Answers2

0

Well, basically following jdweng suggestion:

    public BigInteger GetFrom(decimal value)
    {
        DecimalPlaces = 20;
        string strValue = HasDecimalPlaces(value) ? ConvertAValueWithDecimalPlaces(value) : ConvertARoundedValue(value);
        return BigInteger.Parse(strValue);
    }

    private static bool HasDecimalPlaces(decimal value)
    {
        return ! Math.Round(value).Equals(value) || value.ToString(CultureInfo.InvariantCulture).Contains(".");
    }

    private string ConvertAValueWithDecimalPlaces(decimal value)
    {
        var commaLeftRight = value.ToString(CultureInfo.InvariantCulture).Split('.');
        return commaLeftRight[0] + commaLeftRight[1].PadRight(DecimalPlaces, '0').Substring(0, DecimalPlaces);
    }

    private string ConvertARoundedValue(decimal value)
    {
        return value.ToString(CultureInfo.InvariantCulture) + new string('0', DecimalPlaces);
    }
Andre
  • 652
  • 2
  • 7
  • 23
-1

You should probably implement a solution for utilizing large decimals.

Here is an implementation for a BigDecimal class that you can use.

Here is a different Impl

Here is a library for big numbers and decimals in .Net

TheFastCat
  • 3,134
  • 4
  • 22
  • 32