c++ 10位数而不是18位数的整数溢出?

bvn4nwqk  于 2023-03-05  发布在  其他
关注(0)|答案(1)|浏览(198)
#include <bits/stdc++.h>
using namespace std;
unsigned long long findPeople(double p){
   return ceil(sqrt(2*143545666897673985*log(1/(1-p))));
}
int main(){
   printf("%lld",findPeople(0.5));
}

这是我的代码,我正在尝试计算生日悖论,但使用的数字要大得多(这是一个数学作业),当我使用这个数字(143545666897673985)时,它运行良好,但当我使用另一个数字(1842350265)时,它出现了以下消息:

warning: integer overflow in expression of type ‘int’ results in ‘-610266766’ [-Woverflow]
    4 |    return ceil(sqrt(2*1842350265*log(1/(1-p))));
      |                     ~^~~~~~~~~~~

我是新的编码,我不知道我在做什么。我很困惑,为什么它得到一个10位数的整数溢出,而不是一个18位数。
我试着用unsigned long long,它不应该修复它,它没有。任何帮助是感激的:)

h5qlskok

h5qlskok1#

不带后缀的十进制整数文字类型是intlonglong long中第一个可以保存该值的类型。
int为32位宽而longlong long为64位宽的普通桌面系统上,则

  • 2具有类型int
  • 1842350265具有类型int
  • 143545666897673985具有类型(long) long

在与*相乘时,如果两边都是int类型,则以int类型进行运算。如果第二个操作数是(long) long类型,则以(long) long类型进行运算。
恰好2*1842350265的数学精确值不适合有符号的32位整数(例如int),但2*143545666897673985适合有符号的64位宽整数(例如(long) long)。因此,有符号溢出发生在第一种情况下,而不是后一种情况下。
如果发生了带符号溢出,你不能指望编译器会警告你,它会导致 undefined behavior,这意味着你不能保证程序和编译器会如何运行,你只需要保证它永远不会发生。
由于函数中的所有其他操作都作用于浮点数,而不是整数,所以你可能希望在任何地方都使用浮点数,例如2.0的类型为double143545666897673985.0也是如此,等等。

相关问题