为什么Decimal.MaxValue – 0.5的结果是整数?
我今天正在玩小数。 我注意到了这个:
Decimal.MaxValue 79228162514264337593543950335 Decimal.MaxValue - 0.5m 79228162514264337593543950334
以下代码打印为true。
static void Main(string[] args) { decimal d = Decimal.MaxValue - 0.5M; var b = d % 1 == 0; Console.WriteLine(b); }
我确信这背后有一个原因,但我不知道它是什么。
十进制类型使用96位来存储数字序列( ref ),加上符号(1位)和指定小数位的位置的缩放因子。
对于此十进制数:
79228162514264337593543950335
所有96位都用在小数点的左边 – 没有任何东西可以代表答案的小数部分。 所以,它变得圆润了。
如果您将数字除以10:
7922816251426433759354395033.5
然后你有几个位来表示小数部分 – 但只有1/10,没有更精细。
decimal
和double
/ float
之间的关键区别在于它基于指定小数点位置的小数比例因子; 其他浮点类型基于指定二进制点位置的二进制缩放因子。
在减法之前, 0.5
被舍入。 decimal
努力使结果尽可能精确,因此操作变为79228162514264337593543950335 - 00000000000000000000000000000.5
。 但0.5
不能表示为所需精度的decimal
,而是向上舍入为1
。
它不是整数,实际上是Decimal
。
整数(Int32)的值可以为负2,147,483,648,正数为2,147,483,647。
如您所见,这远远超出了这些范围。
在显示和准确性方面, 79228162514264337593543950334.5
不能用Decimal
表示。
阅读本文以获取更多详细信息(每个计算机科学家应该知道的关于浮点算术的内容)。