C++双精度加运算符

4

可能的重复问题:
浮点数计算不正确?
浮点数编译时计算没有发生?

今天发生了奇怪的事情,我快要失去理智了...

#include <iomanip>
#include <iostream>
using namespace std;

int main()
{
    cout << setprecision(14);
    cout << (1/9+1/9+4/9) << endl;
}

这段代码在MSVC 9.0 x64和x86以及GCC 4.4 x64和x86(默认选项和严格数学运算)上输出0。而据我所记,1/9+1/9+4/9 = 6/9 = 2/3 != 0


而且,就我所记得的,6/9=2/3!=3/9... :) FTFY. - Matteo Italia
4
我很蠢。我知道这一点,只是没想到而已。唉,这里太热了,不利于我的大脑运转。 - rubenvb
8个回答

32

1/9,因为1和9都是整数,进行了整数除法运算。同样的,在4/9中也是如此。

如果你想通过算术字面常量来表示浮点数除法,你必须使用浮点字面常量1.0/9 + 1.0/9 + 4.0/9(或者1/9. + 1/9. + 4/9.1.f/9 + 1.f/9 + 4.f/9),或者显式地将一个操作数强制转换为所需的浮点类型(double) 1/9 + (double) 1/9 + (double) 4/9

附言:终于轮到回答这个问题了 :)


+1,以及加法表达式中的所有其他术语。 - Adam Robinson
2
如果你给double和float命名,那么也可以给long double命名为1L。 - René Wolferink
1
1L是长整型,不是长双精度浮点型,而1L/3仍然是0。 - 6502
1l代表长整型(1l/3 == 0),1L代表长双精度型(1L/3!= 0)。请参阅http://www.cplusplus.com/doc/tutorial/constants/以了解各种常量。 - René Wolferink
4
@René Wolferink: L的大小写无关紧要。当与整数字面值相连时,lL都会使其变成长整型;当与浮点字面值相连时,它们都会使其变成长双精度浮点型(实际上,你链接的那个页面也这样说了)。 @AndreyT: 如果没有小数点或指数,是否需要使用1.0f而不是1f?我认为如果没有小数点或指数,浮点后缀是无效的。 - James McNellis
@James McNellis:您说得完全正确。它必须是浮点字面量,这意味着它至少需要有一个小数点。也就是说,1.f 是可以的,而我的原始 1f 是无效的。 - AnT stands with Russia

7
在计算中使用小数点和这些后缀之一:f l F L,可以强制浮点数运算。如果一个数字没有小数点并且没有这些后缀之一,则不被视为浮点字面量。C++03 2.13.3-1关于浮点字面量的规定如下:浮点字面量由整数部分、小数点、小数部分、e或E、可选符号整数指数以及可选类型后缀组成。整数部分和小数部分都由十进制数字序列组成。整数部分或小数部分(不是两者都有)可以省略;小数点或字母e(或E)和指数(不是两者都有)可以省略。整数部分、可选小数点和可选小数部分组成浮点字面量的有效部分。指数(如果存在)表示要缩放有效部分的10的幂次方。如果缩放后的值在其类型的可表示值范围内,则结果是缩放后的值,如果可表示,则为该值,否则选择最接近缩放后的值的较大或较小的可表示值,以实现定义的方式选择。浮点字面量的类型为double,除非通过后缀明确指定。后缀f和F指定float,后缀l和L指定long double。如果缩放后的值不在其类型的可表示值范围内,则程序是非法的。

2
如果你只是要处理大量分数,可以考虑使用boost::rational。 - Owen S.

6

它们都是整数。所以1/9是0。4/9也是0。而且0 + 0 + 0 = 0。因此结果为0。如果您想要分数,请将您的分数转换为浮点数。


4
1/9(=0)+1/9(=0)+4/9(=0) = 0

3

在C++(和许多其他语言)中,1/9+1/9+4/9的结果是零,因为它是整数运算。

您可能想要写成1/9.0+1/9.0+4/9.0


3

除非你明确指定小数,否则C++使用的数字是整数,因此1/9 = 4/9 = 00 + 0 + 0 = 0

你应该简单地添加小数1.0等等...


3

按照C语言类型规则,这里进行了整数运算。1/9和4/9都被截断为0(作为整数)。如果写成1.0/9.0等形式,它将使用双精度浮点数运算并得到您想要的结果。


-3
你可能会养成使用更多括号的习惯。它们不花费太多时间,可以清楚地表达你的意图,并确保你得到你想要的结果。嗯,大多数情况下... ;)

2
在所发布的表达式中加入括号只会让其变得混乱,使得原本易读的内容变得更加难以阅读。这与手头的问题毫无关系,而添加括号并不能回答发布者的问题。 - sigfpe
1
我完全不同意。添加括号以强制执行顺序可以消除歧义并防止细微错误。我很难相信几个括号会使代码难以阅读。我也不能同意将源代码的可读性放在比代码实际运行更重要的位置。 - Jay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接