C# - 数值变量类型 - Base 2 / Base 10表示法

时间:2013-07-04 00:12:21

标签: c#

有一件小事让我在c#中拼图:)

这是我的变量&结果:

decimal a1 = 0.2M;
decimal a2 = 1.0M;

a1 - a2 = -0.8

float b1 = 0.2F;
float b2 = 1.0F;

b1 - b2 = -0.8

double c1 = 0.2;
double c2 = 1.0;

c1 - c2 = -0.8

double x1 = 0.2F;
double x2 = 1.0F;

x1 - x2 = -0.799999997019768

十进制 - 结果与我预期一样,因为他们知道它们以基数10表示法工作。

Float - 让我感到惊讶,知道它适用于基础2表示法,它实际上显示了结果             好像它作为基础10符号而没有失去精确度。

Double c - 与Float相同。

Double x - 显示我期望Float发生的结果。

问题是 Float Double'c''x'组正在进行的问题?为什么 Double'x'组失去了精确度,而 Float 组实际上是用基数10表示法计算的,这样可以说出“预期”的计算结果?想知道为什么将 Double x 组的数字类型声明为F会如此彻底改变它的出来?

为了它的价值,我只希望十进制组给我'-0.8'的结果,所有其他的东西给'-0.799999997019768'。

看起来我错过了一些关于计算如何处理的理解链接。

2 个答案:

答案 0 :(得分:5)

首先关闭 - 这与base 2与base 10无关。所有值都使用base 10表示。在此代码中不使用Base 2。

  

看起来我错过了一些关于计算如何处理的理解链接。

floatdouble都使用数字的浮点表示,这不是100%准确。当您显示值时,会发生舍入。由于float具有固有的精度,因此它会四舍五入到更少的小数点,这可以使它在某些情况下“显得”更准确(即使它实际上不太精确)。

在您的情况下,“x”组和“c”组显示不同的原因是您声明x1和x2变量是这样的:

double x1 = 0.2F;
double x2 = 1.0F;

这实际上与做:

相同
float temp = 0.2f;
double x1 = temp; // Convert from float to double, which has a loss of precision
temp = 1f;
double x2 = temp; // Convert from float to double, which has a loss of precision

因此,x1x2c1c2的值不完全相同。这导致更多的精度损失,后来,当减法发生时,足以使打印不再圆。

如果您想真正了解这一点,请阅读一篇好文章What Every Computer Scientist Should Know About Floating-Point Arithmetic。大多数常见的编程语言对浮点数使用类似的表示,因此问题相当普遍。

答案 1 :(得分:0)

C#中有一个长期存在的程序员混淆源the language spec allows most intermediate operations on floating-point values to be carried out with extra precision。编译器经常这样做是为了加快速度,因为许多处理器都是这样的。我不清楚具体细节(如果我错了,可以随时纠正我的人),但似乎b部分的计算可能会使用这种额外的精确度。

x组中,double变量已经具有额外的精度,但将float - 类型常量放入其中可能会导致编译器的行为略有不同,导致到不太精确的结果。由于双打已经从它们应该的位置略微偏离,因此完整的double精度只是向前传递错误。

最终,C#中的浮点精度绝不是明确依赖的东西,因为编译器有很大的余地可以根据需要稍微调整一下,但是只要它提供它就会认为它会优化得最好。规范中规定的最低精度。

哦,这与基地2没有任何关系。