C#十进制分区(非常奇怪的行为)

时间:2013-04-10 12:30:49

标签: c# decimal division

任何人都能解释一下吗?

Decimal leftSide = 13.0M;
Decimal rightSide = 1.0M;
Decimal tmpDec = 39.0M;

tmpDec * (rightSide / leftSide) = 2.9999999999999999999999999991

tmpDec * rightSide / leftSide = 3

我是否在第一个(右侧/左侧)丢失有效数字?

3 个答案:

答案 0 :(得分:1)

它正在舍入(失去精确度)问题。

第一种情况首先执行除法并裁剪最后的数字(自小数点后第28位浮点数(或双精度或小数或任何其他固定精度数据类型)不能存储无限长数值),然后执行乘法运算裁员值,增加损失3900万次。这已经变得很重要了(现在不是第28位数,坚果20-22)并且不能四舍五入到3.0。

第二种情况首先执行乘法,它不会松散精度并存储每8位数,然后执行精度较低的除法(小数点后6位)。所以四舍五入已经是3.0而不是2.999999999999999999999,如第一种情况。

答案 1 :(得分:1)

十进制类型仅精确到29位有效数字。

2.9999999999999999999999999991

^超过29位有效数字。

如果您需要更高的精度,可以使用System.Numerics.BigInteger(将其修改为固定点十进制)。

答案 2 :(得分:-1)

将无限多个实数压缩成有限数量的位需要近似表示。尽管存在无限多个整数,但在大多数程序中,整数计算的结果可以以32位存储。相反,给定任何固定数量的位,大多数具有实数的计算将产生无法使用那么多位精确表示的量。因此,浮点计算的结果通常必须舍入,以便适应其有限表示。这种舍入误差是浮点计算的特征