当我进行以下计算时:
unsigned long long int data_size = 60123456 * 128 * sizeof(double);
printf("data_size= %llu \n", data_size);
Run Code Online (Sandbox Code Playgroud)
我出乎意料地得到溢出警告:
test.c:20:49: warning: overflow in expression; result is -894132224 with type 'int' [-Winteger-overflow]
unsigned long long int data_size = 60123456 * 128 * sizeof(double);
^
1 warning generated.
Run Code Online (Sandbox Code Playgroud)
即使我正在使用,我也无法理解为什么会出现此错误unsigned long long int!有人可以解释原因吗?谢谢
Jea*_*bre 45
在将值赋给变量之前发生溢出.为避免使用长long后缀:
60123456LL * 128 * sizeof(double)
Run Code Online (Sandbox Code Playgroud)
(评论还建议ULL在这里没有必要,因为值在符号范围内,但这将是通用的方法)
glg*_*lgl 18
你转得太久了很长时间.60123456 * 128仍然是一个溢出的int表达式.
试试吧60123456LL * 128.(LL,因为结果值不能保证适合长期.)
chu*_*ica 12
unsigned long long int data_size = 60123456 * 128 * sizeof(double); // trouble-some code
Run Code Online (Sandbox Code Playgroud)
目的地类型unsigned long long int data_size =与产品计算无关60123456 * 128 * sizeof(double).
最好确保使用至少目标类型的大小来完成数学运算以避免溢出.在OP的情况下,这意味着一个常数LLU.
有2个产品计算,每个都有自己的类型数学.
60123456是一个int或long取决于int范围.让我们假设它是一个int.
60123456 * 128是一个int * int.数学乘积7695802368超过32位有符号整数 范围,因此带有32位的带符号整数溢出或未定义行为(UB)int.
如果60123456 * 128没有溢出,说64位int,比下的乘法会* sizeof(double);等int * size_t导致size_t的产品类型.
产品计算应至少使用unsigned long long数学如下:
unsigned long long int data_size = 1LLU * 60123456 * 128 * sizeof(double);
// or
unsigned long long int data_size = 60123456LLU * 128 * sizeof(double);
// or
unsigned long long int data_size = 60123456;
data_size *= 128 * sizeof(double);
// or avoiding naked magic numbers
#define A_HEIGHT 60123456
#define A_WIDTH 128
unsigned long long int data_size = 1LLU * A_HEIGHT * A_WIDTH * sizeof(double);
Run Code Online (Sandbox Code Playgroud)
sizeof (double)代码试图找到某些类似2D结构的大小的提示.我希望代码如下.注意结果类型sizeof是size_t,所以产品数学至少使用数学来完成size_t.
size_t data_size = sizeof(double) * 60123456 * 128;
printf("data_size= %zu\n", data_size);
Run Code Online (Sandbox Code Playgroud)
另请参阅为什么在C中将1,000,000,000写入1000*1000*1000? 我的答案理由是不使用1000*1000*1000的适用细节..