??双精度运算符 (C#) 返回不正确的结果



使用 C#,知道为什么以下方法返回 57.99999999999993(而不是58(吗?

double Test_Null_Coalescing_Operator()
{
double? x = 0.58;
return ((x ?? 0) * 100);
}
//returns 57.999999999999993 (instead of 58)

假设 double 是 IEEE 754 64 位二进制浮点数,则 0.58 不能完全表示。最接近的是 0.57999999999999996003197111349436454474925994873046875。乘以 100 后,四舍五入为 58 的舍入误差为

3.99680288865056354552507400512695312500E-15,略大于向下舍入为 57.999999999999999289457264239899814128875732421875, 3.10862446895043831318616867065429687500E-15如果表示长度等物理量,则测量误差将使舍入误差完全相形见绌,小于 1015 分之一。

有一些特殊情况,例如某些财务计算,对于这些情况,短端小数的精确表示很重要。对于这些,通常应使用十进制类型,而不是双精度类型。

舍入误差。 0.58 不作为双精度存在。

@Felipe Deveza已经提到了原因。如果你想只接收 0.58,你可以使用 Math.Round((

答案和链接的副本解释了原因,我只想强调一个经验法则。只要数字的十进制书写表示形式相关,请改用decimal类型。floatdouble类型速度很快,因为它们直接由 CPU 支持,但仅在它们的十进制表示不重要(例如渲染、多媒体处理等(时才使用它们。

在许多语言中,decimal(或用于相同目的的类似十进制浮点类型(称为货币,这表明这是您应该用于财务计算的内容。实际上,这也是 C# 中decimalm后缀的来源(var x = 0.58m(。

最新更新