代码片段
decimal one1 = 10m * 0.1m;
decimal one2 = 10m / 10m;
Console.WriteLine($"{one1}, {one2}, {one1 == one2}");产生的输出:
1.0, 1, True为什么第一个数字用小数点打印,而第二个数字不打印。如果答案在于十进制类型不具有完全表示0.1的精度,那么为什么相等运算符返回true?
发布于 2020-10-07 05:32:49
浮点数是一个复杂的概念,由三个独立的部分组成,它们存储着你认为是数字的信息。
此外,编译器和计算机体系结构对浮点数的处理方式也不明显。当涉及到这些类型的数字时,通常有一些非常奇怪的怪癖;它们如何存储精度;它们可以处理哪些数字,以及编译器和CPU是如何处理它们的数学的。
然而,您获得不同值的原因实际上取决于为该数字所存储的内容。实际上,它们并不是内存中相同的位和字节。相同的数字可以以多种不同的方式存储,并且可以通过不同类型的计算获得(如您所示)。
让我们看看
decimal one1 = 10m * 0.1m;
decimal one2 = 10m / 10m;
int[] bits = decimal.GetBits(one1);
Console.WriteLine("{0,31} {1,10:X8}{2,10:X8}{3,10:X8}{4,10:X8}", one1, bits[3], bits[2], bits[1], bits[0]);
int[] bits2 = decimal.GetBits(one2);
Console.WriteLine("{0,31} {1,10:X8}{2,10:X8}{3,10:X8}{4,10:X8}", one2, bits2[3], bits2[2], bits2[1], bits2[0]);输出
1.0 00010000 00000000 00000000 0000000A
1 00000000 00000000 00000000 00000001正如您所看到的,它们实际上有一个非常不同的二进制布局,这意味着不同的尾数和缩放因子代表着相同的东西。
至于调用ToString()时额外的0,编译器知道重要的零,它们是数字组成的一部分,并根据其比例保持不变。
幸运的是,CLR和体系结构足够聪明,可以分辨出两者的不同之处。
https://stackoverflow.com/questions/64237598
复制相似问题