c#:两个双数问题的总和

时间:2011-03-22 09:04:29

标签: c# double decimal

  

可能重复:
  Why is floating point arithmetic in C# imprecise?

您好。我有以下问题:

43.65+61.11=104.75999999999999
小数的

是正确的:

(decimal)43.65+(decimal)61.11=104.76

为什么双重结果是错误的?

7 个答案:

答案 0 :(得分:11)

这个问题及其答案是关于此的丰富信息 - Difference between decimal, float and double in .NET?

引用:

  
      
  • 对于“天然精确的”值   小数“使用小数表是好的。   这通常适合任何人   人类发明的概念:金融   价值观是最明显的例子,   但也有其他人。考虑一下   得分给潜水员或溜冰者,   例如。

  •   
  • 对于更多人工制品的价值观   无法真正衡量的自然   无论如何,浮动/双倍更多   适当。例如,科学的   数据通常表示为   这个表格。在这里,原始值   将不会“十进制准确”开始   因为它对于这个并不重要   预期结果维持   “十进制精度”。浮动二进制   点类型的工作速度要快得多   超过小数。

  •   

答案 1 :(得分:3)

这不完全是错的。它是由求和产生的二进制浮点数的最接近的十进制表示。

问题在于,由于使用了二进制尾数,IEEE浮点数不能完全代表43.65 + 61.11。某些系统(例如Python 2.7和Visual C ++的标准I / O库)将舍入到解析为相同二进制的最简单小数,并将打印预期的104.76。但所有这些系统在内部都得到完全相同的答案。

有趣的是,十进制表示法可以有限地表示任何有限二进制分数,而相反的情况则不成立。如果人类有两个手指和计算机使用十状态记忆,我们就不会有这个问题。 : - )

答案 2 :(得分:3)

简短回答:浮点表示(例如“double”)本质上是不准确的。固定点也是如此(例如“十进制”),但定点表示的不准确性是另一种类型。这是一个简短的解释:http://effbot.org/pyfaq/why-are-floating-point-calculations-so-inaccurate.htm

您可以谷歌搜索“浮点不准确”或更多信息。

答案 3 :(得分:2)

因为double使用分数模型。任何数字< 1以x / y的形式表示。鉴于该信息,一些数字只能近似。使用十进制,而不是双精度进行高精度计算。

有关轻读的信息,请参阅here:)

答案 4 :(得分:2)

归结为浮点数存储为二进制浮点数,就像在基数10中一样,有些数字在没有截断的情况下无法存储。例如,基数为10的1/3,即.3重复出现。转换为二进制文件时,您正在处理的数字会重复出现。

我不同意浮动或双打比十进制表示更准确或更准确。它们与您选择精确度一样准确。然而,它们是不同的表示,并且可以表示不同于基数10的数字。

Decimal将数字存储在基数10中。这可能会给你预期的结果

答案 5 :(得分:1)

十进制算术非常适合数字的基数10表示,因为基数为10的数字可以用十进制精确表示。 (这就是为什么货币始终始终存储在货币适当的类中,或存储在int中,并使用比例因子来表示'便士'或'便士'或其他类似的十进制货币。)

准确地

IEEE-754 Binary numbers cannot calculate with .1 or .01。因此,浮点格式近似输入,并且您可以获得近似输出,这对于设计用于处理的浮点而言是完全可接受的 - 物理模拟,科学数据和快速数值数学方法。

请注意这个简单的程序和输出:

#include <stdio.h>

int main(int argc, char* argv[]) {
    float f, g;
    double d, e;
    long double l, m;

    f=0.1;
    g=f*f;
    d=0.1;
    e=d*d;
    l=0.1;
    m=l*l;
    printf("%40.40f, %40.40f, %40.40Lf\n", g, e, m);
    return 0;
}

$ ./fp
0.0100000007078051567077636718750000000000,
0.0100000000000000019428902930940239457414,
0.0100000000000000011102569059430467124372

所有这三种可能性都没有给出确切的答案,0.01,但它们确实提供了与答案非常接近的数字。

但是使用十进制算术作为货币。

答案 6 :(得分:0)

真的?以下代码按预期返回 104.76

class Program
{
    static void Main(string[] args)
    {
        double d1 = 43.65;
        double d2 = 61.11;
        double d3 = d1 + d2;
        Console.WriteLine(d3);
        Console.ReadLine();
    }
}

而下面的代码返回 104.76000213623

class Program
{
    static void Main(string[] args)
    {
        float d1 = 43.65f;
        float d2 = 61.11f;
        double d3 = d1 + d2;
        Console.WriteLine(d3);
        Console.ReadLine();
    }
}

检查您是否正在从float转换为double,这可能导致此问题。