明明unsigned long long容量足够却出现整数溢出,如何解决?
问题分析与修复方案
问题根源
你的计算出现错误的核心原因是整数溢出在类型提升前发生:ui->spinBox_2->value() 返回的是 int 类型(Qt的QSpinBox默认返回int),当计算 999 * 60 * 60 * 1000 时,所有操作数都是int,结果 3596400000 超过了int的最大值(通常为2147483647),导致int溢出变成负数。这个负数被转换为unsigned long long时,会被解释为一个极大的正数,也就是你看到的18446744073010984420。
修复方法
解决思路是让乘法运算在unsigned long long类型下执行,避免int阶段的溢出。有几种实现方式:
方式1:强制转换spinBox的值为unsigned long long
unsigned long long int interval = (static_cast<unsigned long long>(ui->spinBox_2->value()) * 60 * 60 * 1000) + (static_cast<unsigned long long>(ui->spinBox_3->value()) * 60 * 1000) + (static_cast<unsigned long long>(ui->spinBox_4->value()) * 1000) + ui->spinBox_5->value();
方式2:用1ULL触发类型提升
在乘法表达式开头加入1ULL(无符号长整型的1),让整个乘法链自动提升为unsigned long long类型:
unsigned long long int interval = (ui->spinBox_2->value() * 1ULL * 60 * 60 * 1000) + (ui->spinBox_3->value() * 1ULL * 60 * 1000) + (ui->spinBox_4->value() * 1ULL * 1000) + ui->spinBox_5->value();
方式3:预定义无符号长整型常量(更易读)
提前定义转换系数为unsigned long long,避免重复处理类型:
const unsigned long long HOUR_TO_MS = 60ULL * 60 * 1000; const unsigned long long MINUTE_TO_MS = 60ULL * 1000; const unsigned long long SECOND_TO_MS = 1000ULL; unsigned long long int interval = (ui->spinBox_2->value() * HOUR_TO_MS) + (ui->spinBox_3->value() * MINUTE_TO_MS) + (ui->spinBox_4->value() * SECOND_TO_MS) + ui->spinBox_5->value();
替代存储方式
由于unsigned long long的最大值(18446744073709551615)远大于最大可能的转换结果(比如1000小时是3600000000,远小于上限),所以完全不需要更换存储类型,修复上述溢出问题即可。
内容的提问来源于stack exchange,提问作者Alan Shiah
相关产品推荐
相关产品推荐

