为什么使用int会出错,但是long long却正确

3
int c;
long long sum=0;
sum+=c*(c-1)/2;

当 c=100000 时,为什么 sum 无法得到正确的答案? 我应该这样写: sum+=(long long)(c*(c-1)/2);
3个回答

5

int 这里假设是32位的 - 100000的平方(10E9)超出了 int 的最大范围,导致溢出。以下代码可以解决这个问题 - 将第一个 c 强制转换为 long long,这样表达式的其余部分就会与 "long long 兼容"。

sum+=((long long)c*(c-1)/2);

1
谢谢,我知道。虽然sum是long long类型,但首先c*(c-1)/2是int类型(因此会溢出),然后它被转换为long long类型。 - outsiders
不客气 - 是的,+= 右侧被评估为 int,因此在转换为 long long 之前发生了溢出。 - Will A

1

因为在计算中使用了 c 作为一个 int,并在存储时将其扩展。

在乘法之前,您需要将其中一个 c 转换为 long long

此外,我建议您考虑使用 int64_t 替代 long long,这样无论如何都可以获得所需的实际类型/大小(请参见 stdint.h 中的各种标识符)。


1

在你的问题中,c 被声明为整数。所以在表达式 c*(c-1) 中它已经超过了整数本身的限制,从而导致了溢出,在其被隐式转换为 long long 之前发生了。这就是 UB 背后的原因。

但是,当你将它隐式地转换为 long long 时,你会得到正确的答案...


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