为什么Decimal.MaxValue - 0.5的结果是整数?

chi*_*kak 5 .net c# decimal

我今天正在玩小数.我注意到了这个:

Decimal.MaxValue 
79228162514264337593543950335

Decimal.MaxValue - 0.5m
79228162514264337593543950334
Run Code Online (Sandbox Code Playgroud)

以下代码打印为true.

static void Main(string[] args)
        {
            decimal d = Decimal.MaxValue - 0.5M;
            var b = d % 1 == 0;
            Console.WriteLine(b);

        }
Run Code Online (Sandbox Code Playgroud)

我确信这背后有一个原因,但我不知道它是什么.

Bev*_*van 11

十进制类型使用96位来存储数字序列(ref),加上符号(1位)和指定小数位的位置的缩放因子.

对于此十进制数:

79228162514264337593543950335
Run Code Online (Sandbox Code Playgroud)

所有96位都用在小数点的左侧 - 没有任何东西可以代表答案的小数部分.所以,它变得圆润了.

如果将数字除以10:

7922816251426433759354395033.5
Run Code Online (Sandbox Code Playgroud)

然后你有几个位可以表示小数部分 - 但只有1/10,没有更精细.

decimaldouble/ 之间的关键区别在于float它基于指定小数点位置的小数比例因子; 其他浮动类型基于指定二进制点位置的二进制缩放因子.

  • @Anton - "十进制"类型主要用于处理金额/货币金额,一个区域人们往往会注意到双重/浮动的缺陷.因此,`decimal`使用*Bankers Rounding*(参见http://en.wikipedia.org/wiki/Rounding).为什么?始终向上舍入0.5会产生统计偏差,导致少量夸大,尤其是在总计一列舍入值时.银行家舍入通过将0.5舍入到最接近的偶数值*来避免这种情况.所以,3.5轮到4.0; 4.5也转到4.0. (4认同)