B bengbu 新手上路 注册 2008-05-05 消息 420 荣誉分数 39 声望点数 38 2012-11-11 #1 #include <iostream> using namespace std; int main(){ double x1=9.0; double x2=10.0; while (x1 < (x2-0.1)) { x2=x2-0.1; } cout << x1 << ", " << x2 << endl; } 为什么最后的输出是: 9, 9 而不是: 9, 9.1 Thanks
#include <iostream> using namespace std; int main(){ double x1=9.0; double x2=10.0; while (x1 < (x2-0.1)) { x2=x2-0.1; } cout << x1 << ", " << x2 << endl; } 为什么最后的输出是: 9, 9 而不是: 9, 9.1 Thanks
E eggplant 资深人士 VIP 注册 2002-08-12 消息 2,021 荣誉分数 609 声望点数 273 2012-11-11 #4 由于精度问题 9.0<9.0 在内存实现时有可能成立,所以会多做一个循环。如果要确保不多做一个循环,应该用类似 9.0-9.0<0.000001,(根据精度需要)
whitegret 大妈 注册 2012-08-20 消息 2,717 荣誉分数 434 声望点数 243 2012-11-11 #5 eggplant 说: 由于精度问题 9.0<9.0 在内存实现时有可能成立,所以会多做一个循环。如果要确保不多做一个循环,应该用类似 9.0-9.0<0.000001,(根据精度需要) 点击展开... 你的意思是有可能是9,9也可能是9,9.1?
eggplant 说: 由于精度问题 9.0<9.0 在内存实现时有可能成立,所以会多做一个循环。如果要确保不多做一个循环,应该用类似 9.0-9.0<0.000001,(根据精度需要) 点击展开... 你的意思是有可能是9,9也可能是9,9.1?
B bengbu 新手上路 注册 2008-05-05 消息 420 荣誉分数 39 声望点数 38 2012-11-11 #6 gina_z 说: 应该用float, 不是double 点击展开... 测试了一下,你是对的。但是,为什么?double不能进行精确比较吗?
Newland 知名会员 注册 2010-10-01 消息 779 荣誉分数 121 声望点数 103 2012-11-11 #7 就应该是 9,9 最后一次满足的条件是 9 〈 9.1, 进入循环体再做一次 X2 = 9.1 - 0.1 = 9
timmy 资深闲人 VIP 注册 2003-02-10 消息 2,538 荣誉分数 1,130 声望点数 373 2012-11-11 #8 eggplant 说: 由于精度问题 9.0<9.0 在内存实现时有可能成立,所以会多做一个循环。如果要确保不多做一个循环,应该用类似 9.0-9.0<0.000001,(根据精度需要) 点击展开... 不对。9.0<9.0是在那都是一定不成立的;是9.1-0.1=9.0在内存表示上不一定成立,所以才有可能x2给跑到了9。
eggplant 说: 由于精度问题 9.0<9.0 在内存实现时有可能成立,所以会多做一个循环。如果要确保不多做一个循环,应该用类似 9.0-9.0<0.000001,(根据精度需要) 点击展开... 不对。9.0<9.0是在那都是一定不成立的;是9.1-0.1=9.0在内存表示上不一定成立,所以才有可能x2给跑到了9。
timmy 资深闲人 VIP 注册 2003-02-10 消息 2,538 荣誉分数 1,130 声望点数 373 2012-11-11 #9 Newland 说: 就应该是 9,9 最后一次满足的条件是 9 〈 9.1, 进入循环体再做一次 X2 = 9.1 - 0.1 = 9 点击展开... 看题不仔细,那是 while (X1 < X2 - 0.1), 不是 while(X1 < X2).
Newland 说: 就应该是 9,9 最后一次满足的条件是 9 〈 9.1, 进入循环体再做一次 X2 = 9.1 - 0.1 = 9 点击展开... 看题不仔细,那是 while (X1 < X2 - 0.1), 不是 while(X1 < X2).
Newland 知名会员 注册 2010-10-01 消息 779 荣誉分数 121 声望点数 103 2012-11-11 #10 timmy 说: 看题不仔细,那是 while (X1 < X2 - 0.1), 不是 while(X1 < X2). 点击展开... 试试x2前面加 volatile
timmy 资深闲人 VIP 注册 2003-02-10 消息 2,538 荣誉分数 1,130 声望点数 373 2012-11-11 #11 Newland 说: 试试x2前面加 volatile 点击展开... 没看出X2是volatile, 加了有用?
E eggplant 资深人士 VIP 注册 2002-08-12 消息 2,021 荣誉分数 609 声望点数 273 2012-11-11 #12 timmy 说: 不对。9.0<9.0是在那都是一定不成立的;是9.1-0.1=9.0在内存表示上不一定成立,所以才有可能x2给跑到了9。 点击展开... 好更正一下。我说的9.0 < 9.0 就是 9.1-0.1<9.0 的意思。总之,两个 double 直接比较是很危险的。因为具体结果同具体的机器硬件有关。16 位,32位,64位可能得到不同结果。正确的应该是 d1-d2<可接受精度。这样保证代码的可移植性。
timmy 说: 不对。9.0<9.0是在那都是一定不成立的;是9.1-0.1=9.0在内存表示上不一定成立,所以才有可能x2给跑到了9。 点击展开... 好更正一下。我说的9.0 < 9.0 就是 9.1-0.1<9.0 的意思。总之,两个 double 直接比较是很危险的。因为具体结果同具体的机器硬件有关。16 位,32位,64位可能得到不同结果。正确的应该是 d1-d2<可接受精度。这样保证代码的可移植性。
B bengbu 新手上路 注册 2008-05-05 消息 420 荣誉分数 39 声望点数 38 2012-11-11 #13 按照gina_z的建议, 将x1, x2定义为float类型,最后的输出是: 9, 9.1 而将x1, x2定义为double类型, 最后的输出是: 9, 9 为什么?
B bengbu 新手上路 注册 2008-05-05 消息 420 荣誉分数 39 声望点数 38 2012-11-11 #14 eggplant 说: 好更正一下。我说的9.0 < 9.0 就是 9.1-0.1<9.0 的意思。总之,两个 double 直接比较是很危险的。因为具体结果同具体的机器硬件有关。16 位,32位,64位可能得到不同结果。正确的应该是 d1-d2<可接受精度。这样保证代码的可移植性。 点击展开... #include <iostream> using namespace std; int main(){ double x1=9.0; double x2=10.0; while (0.1 < (x2-x1)){ x2=x2-0.1; } cout << x1 << " " << x2 << endl; system("pause"); } 按照您的建议,改了判断,但结果仍是依旧。 将x1, x2定义为float类型,最后的输出是: 9, 9.1 而将x1, x2定义为double类型, 最后的输出是: 9, 9 为什么?
eggplant 说: 好更正一下。我说的9.0 < 9.0 就是 9.1-0.1<9.0 的意思。总之,两个 double 直接比较是很危险的。因为具体结果同具体的机器硬件有关。16 位,32位,64位可能得到不同结果。正确的应该是 d1-d2<可接受精度。这样保证代码的可移植性。 点击展开... #include <iostream> using namespace std; int main(){ double x1=9.0; double x2=10.0; while (0.1 < (x2-x1)){ x2=x2-0.1; } cout << x1 << " " << x2 << endl; system("pause"); } 按照您的建议,改了判断,但结果仍是依旧。 将x1, x2定义为float类型,最后的输出是: 9, 9.1 而将x1, x2定义为double类型, 最后的输出是: 9, 9 为什么?
K kpmgtd 知名会员 VIP 注册 2004-05-24 消息 589 荣誉分数 81 声望点数 188 2012-11-11 #15 浮点数,包括float和double的比较都是不精确的 即使您这次用float似乎得到了你想要的结果,也不表明下次别的浮点运算就能准确。常用的一个方法是在你的判断式中加上一个误差,从而能够抵消有限位计算机表示无限精确数字(理论上)时不可避免的误差。 比如: delta = 1e-32; while (x1 < x2-0.1-delta){ ... } 应该能够保证你得到想要的结果,即使你用double类型。 delta的设置与特定机器的精度有关。你可以GOOGLE一下你的机器上double的精度,从而确定最小的delta值。当然对于已知的问题,delta大一点也没关系。 注意 +/- delta 的应用。其实更常见的是要比较两个float或double是否相等 (比如在解不定方程时那样)。如果你需要断定X1是否等于X2(在浮点运算中实际上是不可能的),你就需要用到 #define eq(x1, x2) (x1 > x2-delta) && (x1 < x2+delta) ? 1:0 (不好意思,C/C++的句法有点忘了,基本意思如此)
浮点数,包括float和double的比较都是不精确的 即使您这次用float似乎得到了你想要的结果,也不表明下次别的浮点运算就能准确。常用的一个方法是在你的判断式中加上一个误差,从而能够抵消有限位计算机表示无限精确数字(理论上)时不可避免的误差。 比如: delta = 1e-32; while (x1 < x2-0.1-delta){ ... } 应该能够保证你得到想要的结果,即使你用double类型。 delta的设置与特定机器的精度有关。你可以GOOGLE一下你的机器上double的精度,从而确定最小的delta值。当然对于已知的问题,delta大一点也没关系。 注意 +/- delta 的应用。其实更常见的是要比较两个float或double是否相等 (比如在解不定方程时那样)。如果你需要断定X1是否等于X2(在浮点运算中实际上是不可能的),你就需要用到 #define eq(x1, x2) (x1 > x2-delta) && (x1 < x2+delta) ? 1:0 (不好意思,C/C++的句法有点忘了,基本意思如此)