C# 值对于小数来说太大的解决方法
C# Workaround for Value too large for a Decimal
我有一个函数非常适用于不太大的值:
public BigInteger GetFrom(decimal value)
{
var decimalPlaces = 20;
var factor = (decimal) Math.Pow(10, decimalPlaces);
return new BigInteger(value * factor);
}
正确转换:
123m = 12300000000000000000000
123.123456789m = 12312345678900000000000
0.123m = 12300000000000000000
0.123456789m = 12345678900000000000
0.123456789012345678902345678901234567890m = 12345678901234567890
1.123456789012345678902345678901234567890m = 112345678901234567890
但是要找这样的东西:12345678901234567890.12345678901234567890m。
当然,因为 12345678901234567890.12345678901234567890m * Math.Pow(10, 20) 对于小数来说太大了,但我不需要它作为小数,我需要它作为 BigInteger 就像之前的例子
12345678901234567890.12345678901234567890m = 1234567890123456789012345678901234567890
购买,我不确定what/how是否是解决此问题的最佳方法...
您或许应该实施一个利用大小数的解决方案。
Here is an implementation for a BigDecimal class that you can use.
Here is a different Impl
嗯,基本上按照jdweng的建议:
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);
}
我有一个函数非常适用于不太大的值:
public BigInteger GetFrom(decimal value)
{
var decimalPlaces = 20;
var factor = (decimal) Math.Pow(10, decimalPlaces);
return new BigInteger(value * factor);
}
正确转换:
123m = 12300000000000000000000
123.123456789m = 12312345678900000000000
0.123m = 12300000000000000000
0.123456789m = 12345678900000000000
0.123456789012345678902345678901234567890m = 12345678901234567890
1.123456789012345678902345678901234567890m = 112345678901234567890
但是要找这样的东西:12345678901234567890.12345678901234567890m。 当然,因为 12345678901234567890.12345678901234567890m * Math.Pow(10, 20) 对于小数来说太大了,但我不需要它作为小数,我需要它作为 BigInteger 就像之前的例子
12345678901234567890.12345678901234567890m = 1234567890123456789012345678901234567890
购买,我不确定what/how是否是解决此问题的最佳方法...
您或许应该实施一个利用大小数的解决方案。
Here is an implementation for a BigDecimal class that you can use.
Here is a different Impl
嗯,基本上按照jdweng的建议:
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);
}