??双重运算符(C#)返回错误结果

时间:2018-10-10 03:31:12

标签: c# null double coalescing null-coalescing

使用C#,是否知道以下方法为何返回 57.999999999999993 (而不是 58 )?

double Test_Null_Coalescing_Operator()
{
    double? x = 0.58;
    return ((x ?? 0) * 100);
}

//returns 57.999999999999993 (instead of 58)

4 个答案:

答案 0 :(得分:3)

假设double是IEEE 754 64位二进制浮点数,则0.58不能精确表示。最接近的是0.57999999999999996003197111349436454474925994873046875。乘以100后,四舍五入到58的舍入误差将是3.99680288865056354552507400512695312500E-15,这略大于四舍五入到57.99999999999999289457264239899814814875875421421,3.10862446895095043831318616867065429687500E-15

如果要表示长度之类的物理量,则测量误差将使舍入误差完全相形见,,不到10 15 的十分之一。

在某些特殊情况下(例如某些财务计算),精确表示短终止小数部分非常重要。对于这些,通常应使用十进制类型,而不要使用双精度类型。

答案 1 :(得分:1)

答案 2 :(得分:0)

@Felipe Deveza已经提到了原因。如果您想精确接收0.58,则可以使用Math.Round()

答案 3 :(得分:0)

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

在许多语言中,decimal(或出于相同目的的类似十进制浮点类型)被称为 money ,这表明您应该在财务计算中使用该货币。实际上,这也是m的{​​{1}}后缀来自C#(decimal)的地方。