以下测试为您的函数返回0
:
#include <stdio.h>
#include <limits.h>
int test_dl2(int x,int y) {
long long lsum = (long long) x + y;
return lsum == (int) lsum;
}
int main() {
printf("%d",test_dl2(INT_MAX,1));
return 0;
}
我使用的数字是导致溢出的int
的最大值。您的代码用于测试int
中的溢出,因此您需要使用引起+
的{{1}}中溢出的值进行测试。有很多测试表明这种溢出,而我只是一个例子。
更新:
如注释中所述,int
属于lsum == (int) lsum
中定义的实现中的代码部分,因此您根本无法传递函数结果。如果数据类型是无符号的(C
和unsigned int
),我的观点是正确的。此代码也是在unsigned long long
中的C++20
之前定义的实现。在C++
之后,它再次在C++20
中定义。
,
也许您正在尝试检查添加 x 和 y 是否会给出uint32_t的有效结果。正如评论中已经指出的那样,问题在于,如果数字太大,则从uint64_t到uint32_t的转换是不确定的。
目前C和C ++都没有假设数字表示为二进制补码,因此很难进行这种验证。这将改变,因为下一个C ++标准将强制使用two's complement to code signed integers(并且可能会遵循C标准)。
但这不会表示错误的转换,并且您的代码仍然无效。
如果我们假设数字以二进制补码编码(这已经是大多数计算机中的行为),则可以完成一些测试。
可以使用几种解决方案。这是一种主要依赖于按位运算符的程序。
该方法的概述是:
-
左移数字将它们除以2(假设带符号的左移是算术运算,在大多数计算机上都是如此,但标准目前尚无此要求)
-
添加它们。这将计算 x / 2 + y / 2 ,并且等于(x + y)/ 2 ,除非,如果两个LSB均 x 和 y 是1,在这种情况下, x + y 中会产生一个权重为2 ^ 1的进位。
我们通过 x 和 y 的最低有效位(LSB)来测试此进位的存在,并将其加到和中。
-
上一个计算(x + y)/ 2 的结果始终对32位有效。我们检查31位是否有效。如果为true, x + y 将在32位上有效。
仅通过比较第31位和第30位来检查此有效性。如果它们相等,则可以安全地将结果转换为31位。否则,转换将导致符号变化。
int is_add32_valid(uint32_t x,uint32_t y) {
uint32_t z = (x>>1) + (y>>1) + (x & y & 0x1) ;
return !( (z ^ (z <<1)) & (1 << 31) ) ;
}
,
如果x + y大于tmax或小于tmin,则应返回0。
否则它将返回1。
本文链接:https://www.f2er.com/3168882.html