Arbitrary-Precision Decimals in C# [duplicate]
Asked Answered
L

3

7

Possible Duplicates:
Big integers in C#
C# unlimited significant decimal digits (arbitrary precision) without java

I read the question at Arbitrary precision decimals in C#? but I don't have the J# library. I need a library for arbitrary precision decimals with C#.

Leveret answered 24/12, 2010 at 1:50 Comment(2)
Since neither of the proposed duplicates actually answers the question, I'm voting to reopen. The other answers are just to use decimal, BigInteger, or the J# libraries.Maricruzmaridel
The J# runtime library IS a library for arbitrary precision decimals in any .NET language, C# included.Tswana
B
3

Big Decimal:

Big Int (If you like J.D.'s solution, or want to come up with a rational number/fraction type class. That, and I somehow missed that you were looking for decimals, not ints):

Bertine answered 24/12, 2010 at 2:21 Comment(2)
BigInteger and IntX are integer-only; they have no support for decimals.Maricruzmaridel
@Gabe: Ugh, that's true. Well, J# is free at least :)Bertine
A
15

You could implement your own based on .NET 4.0's BigInteger class. I did this for fun, it does multiplication only:

public struct BigDecimal {
    public BigInteger Integer { get; set; }
    public BigInteger Scale { get; set; }

    public BigDecimal(BigInteger integer, BigInteger scale) : this() {
        Integer = integer;
        Scale = scale;
        while (Scale > 0 && Integer % 10 == 0) {
            Integer /= 10;
            Scale -= 1;
        }
    }

    public static implicit operator BigDecimal(decimal a) {
        BigInteger integer = (BigInteger)a;
        BigInteger scale = 0;
        decimal scaleFactor = 1m;
        while ((decimal)integer != a * scaleFactor) {
            scale += 1;
            scaleFactor *= 10;
            integer = (BigInteger)(a * scaleFactor);
        }
        return new BigDecimal(integer, scale);
    }

    public static BigDecimal operator *(BigDecimal a, BigDecimal b) {
        return new BigDecimal(a.Integer * b.Integer, a.Scale + b.Scale);
    }

    public override string ToString() {
        string s = Integer.ToString();
        if (Scale != 0) {
            if (Scale > Int32.MaxValue) return "[Undisplayable]";
            int decimalPos = s.Length - (int)Scale;
            s = s.Insert(decimalPos, decimalPos == 0 ? "0." : ".");
        }
        return s;
    }
}

...

decimal d1 = 254727458263237.1356246819m;
decimal d2 = 991658834219519273.110324m;
// MessageBox.Show((d1 * d2).ToString()); // OverflowException
BigDecimal bd1 = d1;
BigDecimal bd2 = d2;
MessageBox.Show((bd1 * bd2).ToString()); // 252602734305022989458258125319270.5452949161059356
Altamira answered 24/12, 2010 at 4:43 Comment(5)
I suggest using s.Insert(decimalPos, ".") instead of calling substring twice and concatenating.Tswana
Also, using BitInteger for scale seems overkill. You really think there's a need to support numbers outside the range 10**(-263) to bigint * 10**(263 - 1) ???Tswana
This is actually pretty good, but BigDecimal should probably be a struct and, as Ben suggested, the scale should probably be an int.Maricruzmaridel
I really liked that idea and completed the draft to support all basic operators, see my answer here: https://mcmap.net/q/300892/-what-is-the-equivalent-of-the-java-bigdecimal-class-in-cWhet
BigDecimal * BigDecimal variable not giving correct result. how can we achieve this? Example - BigDecimal bd1 = new BigDecimal(1234567890123,1234567890123); BigDecimal bd2 = new BigDecimal(1234567890123, 1234567890123); Console.WriteLine("\n" + (bd1 * bd2).ToString()); Fakery
B
3

Big Decimal:

Big Int (If you like J.D.'s solution, or want to come up with a rational number/fraction type class. That, and I somehow missed that you were looking for decimals, not ints):

Bertine answered 24/12, 2010 at 2:21 Comment(2)
BigInteger and IntX are integer-only; they have no support for decimals.Maricruzmaridel
@Gabe: Ugh, that's true. Well, J# is free at least :)Bertine
M
3

There's always the GNU MP wrapper for .NET as long as you don't mind using the GMP.

Maricruzmaridel answered 24/12, 2010 at 5:18 Comment(1)
Link seems dead.Balcony

© 2022 - 2024 — McMap. All rights reserved.