将BigDecimal Java转换为类似c#的Decimal



在Java中,BigDecimal类包含A*pow(10,B)等值,其中A是2的非固定位长度补码,B是32位整数。

在C#Decimal中,包含pow(-1,s)×C×pow(10,-e)的值,其中符号s为0或1,系数C由0≤C<pow(2,96),标度e为0≤e≤28。

我想把Java中的BigDecimal转换成Java中的c#Decimal。你能帮我吗。

我有一些类似的东西

class CS_likeDecimal
{
     
    private int hi;// for 32bit most sinificant bit of c 
    private int mid;// for 32bit in the middle  
    private int lo;// for 32 bit the last sinificant bit
    .....
    public CS_likeDecimal(BigDecimal data)
    {
                ....
    }
}

事实上,我发现了这个What';这是表示协议缓冲区中的System.Decimal的最佳方式?。

它是一个发送c#十进制的协议缓冲区,但在protobuff网络项目中,使用它在c#之间发送消息(但我想在c#和JAVA之间)

message Decimal {
  optional uint64 lo = 1; // the first 64 bits of the underlying value
  optional uint32 hi = 2; // the last 32 bis of the underlying value
  optional sint32 signScale = 3; // the number of decimal digits, and the sign

}

谢谢,

我在protobuf网络中使用的Decimal主要用于支持管道两端使用的protobuf网的可能使用,该网络支持固定范围。听起来讨论中的两种类型的范围不一样,所以:不完全兼容。

我建议明确使用替代表示。我不知道Java的BigDecimal可以使用什么表示——是实用的byte[]版本,还是string版本。

如果你确信比例和范围不会成为问题,那么应该可以在两种布局之间进行一些篡改。

我需要编写一个到.Net Decimal的BigDecimal转换器。使用此参考:http://msdn.microsoft.com/en-us/library/system.decimal.getbits.aspx我写了这个代码可以工作:

public static byte[] BigDecimalToNetDecimal(BigDecimal paramBigDecimal) throws IllegalArgumentException
{
    // .Net Decimal target
    byte[] result = new byte[16];
    // Unscaled absolute value
    BigInteger unscaledInt = paramBigDecimal.abs().unscaledValue();
    int bitLength = unscaledInt.bitLength();
    if (bitLength > 96)
        throw new IllegalArgumentException("BigDecimal too big for .Net Decimal");
    // Byte array
    byte[] unscaledBytes = unscaledInt.toByteArray();
    int unscaledFirst = 0;
    if (unscaledBytes[0] == 0)
        unscaledFirst = 1;
    // Scale
    int scale = paramBigDecimal.scale();
    if (scale > 28)
        throw new IllegalArgumentException("BigDecimal scale exceeds .Net Decimal limit of 28");
    result[1] = (byte)scale;
    // Copy unscaled value to bytes 8-15 
    for (int pSource = unscaledBytes.length - 1, pTarget = 15; (pSource >= unscaledFirst) && (pTarget >= 4); pSource--, pTarget--)
    {
        result[pTarget] = unscaledBytes[pSource];
    }
    // Signum at byte 0
    if (paramBigDecimal.signum() < 0)
        result[0] = -128;
    return result;
}
public static BigDecimal NetDecimalToBigDecimal(byte[] paramNetDecimal)
{
    int scale = paramNetDecimal[1];
    int signum = paramNetDecimal[0] >= 0 ? 1 : -1;
    byte[] magnitude = new byte[12];
    for (int ptr = 0; ptr < 12; ptr++) magnitude[ptr] = paramNetDecimal[ptr + 4];
    BigInteger unscaledInt = new BigInteger(signum, magnitude);
    return new BigDecimal(unscaledInt, scale);
}

最新更新