您好。我有以下问题:
43.65+61.11=104.75999999999999
小数的是正确的:
(decimal)43.65+(decimal)61.11=104.76
为什么双重结果是错误的?
答案 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,这可能导致此问题。