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
How to Access HTML Form Input from ASP.NET Code Behind
Conversion of System.Array to List
Authorize by Group in Azure Active Directory B2C
Why Must I Provide Explicitly Generic Parameter Types While the Compiler Should Infer the Type
Xml Serialization and Inherited Types
When Should I Use "Using" Blocks in C#
Using a Self-Signed Certificate with .Net's Httpwebrequest/Response
No Concurrentlist<T> in .Net 4.0
Kanji Characters from Webclient HTML Different from Actual Kanji in Website
Unauthorised Webapi Call Returning Login Page Rather Than 401
Why Should I Implement Icloneable in C#
System.Lazy<T> with Different Thread-Safety Mode
How to Run a C# Application at Windows Startup
Embedding an External Executable Inside a C# Program
Frombody String Parameter Is Giving Null
Multiple Actions Were Found That Match the Request in Web API