我是新来的,所以非常抱歉,如果这是基本的,但我在这里缺少什么?这只是一个虚拟代码:
#include <iostream>
using namespace std;
int main() {
unsigned int a, b, c;
int d;
a = 10E06;
b = 25E06;
c = 4096;
d = (a - b)/c;
std::cout << d << std::endl;
return 0;
}
cout正在打印1044913而不是-3662。如果我把a和b转换成长期问题就解决了。是否存在溢出问题?
答案 0 :(得分:4)
那是因为(a-b)
本身是无符号的:
#include <iostream>
using namespace std;
int main() {
unsigned int a, b, c;
int d;
a = 10E06;
b = 25E06;
c = 4096;
d = (a - b)/c;
std::cout << (a-b) << std::endl; // 4279967296
std::cout << d << std::endl; // 1044913
return 0;
}
unsigned
转换为int
时会发生d
,而不是之前。
所以(a-b)/c
必须是无符号的,因为a,b,c
是。
答案 1 :(得分:3)
无符号数之间的运算产生无符号数。这取决于你确保操作有意义,或防止相反。
如果您有unsigned int a = 2, b = 3;
,您认为a-b
的价值是什么?
答案 2 :(得分:2)
由于b和c都被声明为无符号,因此计算(a-b)/ c的输出将是无符号的。由于您提供的值的计算无法使用无符号类型正确表示,因此事情变得有点混乱。然后将无符号值分配给d,即使这是有符号的,该值也已经是乱码。
我还要注意,符号10E06表示一个浮点数,然后隐式地转换为unsigned int。根据提供的特定浮点值,这可能会或可能不会按预期进行投射。
答案 3 :(得分:1)
您希望您的结果带有标志。因此,您应该将变量声明为signed int或int。这将产生预期的结果。如果你将a和b转换为long,a-b将会很长,因此需要一个符号。以下是一个解决方案。
int main() {
int a, b, c;
int d;
a = 10E06;
b = 25E06;
c = 4096;
d = (a - b)/c;
std::cout << d << std::endl;
return 0;
}
如果你也想要有理数,你应该使用双打或浮点数(尽管它不会为这个特殊情况给出不同的结果)。
int main() {
double a, b, c;
double d;
a = 10E06;
b = 25E06;
c = 4096;
d = (a - b)/c;
std::cout << d << std::endl;
return 0;
}
答案 4 :(得分:1)
由于C ++(以及许多其他基于C语言)处理运算符的方式,当无符号数放入表达式时,该表达式返回无符号值,而不是保持在一个神秘的类型间状态,可能是预期
步骤一步:
(a - b)
从10E06中减去25E06,它通常会返回-15E06,是无符号的,所以它被包裹在一大堆垃圾中。“unsigned int”是一个类似float和bool的类型,即使它需要两个关键字。如果您希望它变成用于该计算的signed int,则必须确保a,b和c都已签名(删除unsigned关键字),或者在将它们放入表达式时将其强制转换,如下所示: d = ((signed)a - (signed)b) / (signed)c;