考虑以下两段代码 - 它们之间唯一的区别是一个cout打印值eps:
http://ideone.com/0bEeHz - 此处程序进入并且无限循环,因为在cout eps将值更改为0
#include <iostream>
int main()
{
double tmp = 1.;
double eps;
while(tmp != 0) {
eps = tmp;
tmp /= 2.;
}
if(eps == 0) {
std::cout << "(1)eps is zero!\n";
}
std::cout << "eps before: " << eps;
if(eps == 0) {
std::cout << "(2)eps is zero!\n";
}
while(eps < 1.) {
tmp = eps;
eps *= 2.;
if(tmp == eps) {
printf("wtf?\n");
}
}
std::cout << "eps after: " << eps;
}
http://ideone.com/pI4d30 - 我在这里评论了这个cout。
#include <iostream>
int main()
{
double tmp = 1.;
double eps;
while(tmp != 0) {
eps = tmp;
tmp /= 2.;
}
if(eps == 0) {
std::cout << "(1)eps is zero!\n";
}
//std::cout << "eps before: " << eps;
if(eps == 0) {
std::cout << "(2)eps is zero!\n";
}
while(eps < 1.) {
tmp = eps;
eps *= 2.;
if(tmp == eps) {
printf("wtf?\n");
}
}
std::cout << "eps after: " << eps;
}
因此,一个单独的cout显着地且非常令人惊讶地改变了程序逻辑。那是为什么?
答案 0 :(得分:2)
我认为这是第5节(表达式)第11段的案例
浮动操作数的值和浮动表达式的结果可以表示为比类型所需的精度和范围更高的精度和范围;因此,类型不会改变。
在工作中,参见this variation原始代码。
while(tmp != 0) {
eps = tmp;
tmp /= 2.;
}
以扩展精度执行的计算和比较。循环运行直到eps
是最小的正扩展值(可能是80位x87扩展类型)。
if(eps == 0) {
std::cout << "(1)eps is zero!\n";
}
仍处于扩展精度eps != 0
std::cout << "eps before: " << eps;
要转换为要打印的字符串,eps
将被存储并转换为double
精度,结果为0。
if(eps == 0) {
std::cout << "(2)eps is zero!\n";
}
是的,现在是。