What Is the Equivalent of the Java Bigdecimal Class in C#

What is the equivalent of the Java BigDecimal class in C#?

C# only has BigInteger built it (in .NET framework 4).

Is decimal enough precision for your task? It's a 128-bit number that can hold values in the range ±1.0 × 10−28 to ±7.9 × 1028.

Java BigDecimal , equivalent of C#'s Decimal(int[] bits) Constructor

In Java, you'd use BigDecimal. That's not quite the same type, but it's reasonably close.

You just need to reconstruct the 96-bit integer as a BigInteger, then scale it and optionally negate it:

import java.math.BigDecimal;
import java.math.BigInteger;

public class Test {

public static void main(String[] args) {
int[] parts = { 2020, 0, 0, 131072 };
BigInteger integer = BigInteger.valueOf(parts[2] & 0xffffffffL).shiftLeft(32)
.add(BigInteger.valueOf(parts[1] & 0xffffffffL )).shiftLeft(32)
.add(BigInteger.valueOf(parts[0] & 0xffffffffL));
BigDecimal decimal = new BigDecimal(integer, (parts[3] & 0xff0000) >> 16);
if (parts[3] < 0) // Bit 31 set
{
decimal = decimal.negate();
}
System.out.println(decimal);
}
}

Output:

20.20

The masking when constructing the BigInteger parts is there to effectively treat the values as unsigned - performing a bitwise AND with a long with the top 32 bits clear and the the bottom 32 bits set, we're constructing the same numeric value you'd get by casting each int to uint in C#.

Is Java's BigDecimal the closest data type corresponding to C#'s Decimal?

Yep - that's the corresponding type.

Since you are using Java after C# - don't be too surprised to find little nuances like this - or be too upset when there is no easy way to do something that's "easy" to do C#. The first thing that comes to my mind is int & int? - in Java you just use int and Integer.

C# had the luxury of coming after Java so lots of (what I subjectively see as) bad decisions have been fixed/streamlined. Also, it helps that C# was designed by Andres Hejlsberg (who is arguably one of the best programming language designers alive) and is regularly "updated" unlike Java (you probably witnessed all things added to C# since 2000 - complete list)

conversion BigDecimal Java to c#-like Decimal

the Decimal I use in protobuf-net is primarily intended to support the likely usage of protobuf-net being used at both ends of the pipe, which supports a fixed range. It sounds like the range of the two types in discussion is not the same, so: are not robustly compatible.

I would suggest explicitly using an alternative representation. I don't know what representations are available to Java's BigDecimal - whether there is a pragmatic byte[] version, or a string version.

If you are confident that the scale and range won't be a problem, then it should be possible to fudge between the two layouts with some bit-fiddling.

C# equivalent of BigDecimal.stripTrailingZeros()

Here is what i have come up with (Crazy code but works smoothly)

private decimal Normalize(decimal d)
{
string[] tmp = d.ToString().Split('.');
string val = tmp[0];
string fraction = null;
decimal result;
if(tmp.Length > 1) fraction = tmp[1];
if(fraction != null && Getleast(fraction) > 0)
{
decimal.TryParse(val.ToString() + "." + fraction.TrimEnd('0').ToString(),out result);
}
else
{
return decimal.Parse(val);
}
return result;
}

private decimal Getleast(string str)
{
decimal res;
decimal.TryParse(str.TrimEnd('0'),out res);// It returns 0 even if we pass null or empty string
return res;
}

Here are sample Input:

Console.WriteLine(Normalize(0.00M));
Console.WriteLine(Normalize(0.10M));
Console.WriteLine(Normalize(0001.00M));
Console.WriteLine(Normalize(1000.01M));
Console.WriteLine(Normalize(1.00001230M));
Console.WriteLine(Normalize(0031.200M));
Console.WriteLine(Normalize(0.0004000M));
Console.WriteLine(Normalize(123));

And respective output:

0
0.1
1
1000.01
1.0000123
31.2
0.0004
123

Java's equivalent of C# Big Rational

There is not (if you don't like BigDecimal); however, you can make a class to represent it using BigInteger and BigDecimal. An example is found here.

Java's equivalent of C# Big Rational

There is not (if you don't like BigDecimal); however, you can make a class to represent it using BigInteger and BigDecimal. An example is found here.

C# Double Rounding

Couldn't you just do this to round to 2 fractional digits?

        double foo = 3.143;
double fooRounded = Math.Round(foo, 2);


Related Topics



Leave a reply



Submit