C语言 在算术之前限制两个变量的位位置,以防止整数溢出



我试图在执行算术运算之前将算术运算限制为最多 32 位整数的结果,特别是用于加法。

此循环将找到位位置:

 size_t highestOneBitPosition(uint32_t a) {
     size_t bits=0;
     while (a!=0) {
         ++bits;
         a>>=1;
     };
     return bits;
 }

此函数有效地限制乘法:

 bool multiplication_is_safe(uint32_t a, uint32_t b) {
     size_t a_bits=highestOneBitPosition(a), b_bits=highestOneBitPosition(b);
     return (a_bits+b_bits<=32);
 }

但是,我不确定如何通过添加来做到这一点。像这样:

bool addition_is_safe(uint32_t a, uint32_t b) {
size_t a_bits=highestOneBitPosition(a), b_bits=highestOneBitPosition(b);
return (a_bits<32 && b_bits<32);
}

但是,这不会将整数限制为 32 位(或有符号的 0x7FFFFFFF(。它将确保每个操作数都有那么多位位置。

从数学上讲,如果将两个数字相加,则最多有 1 进入最长位置。因此,如果您在 3 位数字(或任何 4 位或更少的数字(中添加一个 4 位数字,则最多有一个 5 位数字。除了,当你有两个相同的时,你最终可以得到更多(99 * 99 = 9801(,所以它将与乘法(a_bits+b_bits <=32(的概念相同

我要做的就是确定最长的操作数,然后加 1 并确保它不超过 32 位位置。我完全不确定如何使用函数来做到这一点。我的问题是我如何修改 addition_is_safe(uint32_t a、uint32_t b( 以将结果限制为 <=32,因为它在 multiplication_is_safe 中。我绝对想利用这个最高的一个位位置。

首先,我什至不认为这个函数是正确的:

bool multiplication_is_safe(uint32_t a, uint32_t b) {
     size_t a_bits=highestOneBitPosition(a), b_bits=highestOneBitPosition(b);
     return (a_bits+b_bits<=32);
}

当乘法溢出时,它确实会返回false,但当乘法没有溢出时,它也会返回false。 例如,给定 a = 0x10000 且 b = 0x8000 ,即使 a*b 的结果是 0x80000000 适合 32 位,此函数也返回 false。 但是,如果您将 a 和 b 更改为 0x1ffff0xffff(它们具有相同的"最高一位位置"(,那么乘法实际上确实会溢出。 但是你不能只使用最高的位位置来判断。 您需要查看的不仅仅是顶部位来确定乘法是否会溢出。 事实上,你需要做部分或全部的实际乘法才能找出正确的答案。

类似地,您可以构造一个函数addition_is_safe,该函数使用位位置检测"可能的溢出"(正向和负向(。 但是,除非您执行部分或全部实际添加,否则无法检测到"实际溢出"。

我相信在最坏的情况下,您将被迫进行完整的乘法或加法,所以我不确定您不会因为不让机器为您执行完整的乘法/加法来节省任何东西。

在数学上,如果将两个数字相加,则最多有 1 的进位 进入最长的地方。

这是绝对正确的(对于无符号的二进制数(,无一例外;你只是迷失在进一步的考虑中。因此,基于总和位数的addition_is_safe条件是:总和的最大位数必须小于可用位数。

bool addition_is_safe(uint32_t a, uint32_t b)
{
    size_t a_bits=highestOneBitPosition(a), b_bits=highestOneBitPosition(b);
    return (a_bits<b_bits?b_bits:a_bits)<32;
}

当然,您知道该函数的false返回并不总是意味着会发生溢出,但true返回意味着不会发生溢出。

您可以通过使用(a + b) < a || (a + b) < b添加两个正整数来检查

溢出

溢出将使值为负(对于有符号整数(,或者将保留较小的正模式 32 余数(对于无符号(

正加到负永远不会溢出

两个

负数应类似于两个正数

相关内容

  • 没有找到相关文章

最新更新