我正在尝试在C ++中执行以下算法。这样做C ++(gcc(Ubuntu / Linaro 4.6.4-6ubuntu2)4.6.4)给出了无限的输出。虽然输出应该是0.1001。有人可以解释一下C ++编译器的奇怪行为吗
unsigned man=10009999,exp1=8;
double retrievedVal=(man)*pow(10,-((exp1)));
cout<<"retrieved val="<<retrievedVal<<"\n";
Ouput: inf
答案 0 :(得分:3)
如果否定无符号整数,则无法得到预期的结果。这可以通过以下代码轻松验证:
#include <iostream>
int main() {
unsigned a = 8;
double b = -((a));
std::cout << b;
}
输出:
4.29497e+009
要修复它,请将exp1更改为常规int
,或使用强制转换(不推荐,您应该更喜欢只更改类型)。
在无符号类型上,所有代表带符号类型中负数的值实际上代表一个(通常非常大)正数。
在具有32位整数的2补码机器中,8
将表示为0000 0000 0000 0000 0000 0000 0000 1000
。 -8
实际上由1111 1111 1111 1111 1111 1111 1111 1000
表示。但是你正在处理一个无符号的,它将这个相同的表示视为正数。现在,相同的二进制数据代表4294967288
。 10这个值的力量肯定会溢出一倍,这就是你获得inf
的原因。
答案 1 :(得分:2)
不要否定无符号值。一个脏修复将转换为您的输出变量类型。 。
double retrievedVal=man*pow(10,-(double)exp1);