是否有添加在一个整数的端部的位而不将其转换为字符串,并在不使用stringstreams的一种安全的方法?

我想谷歌的答案,这和大多数解决方案建议将其转换为字符串,并使用stringstreams,但我想保持它作为一个整数,以确保数据的完整性,避免类型转换。结果 我也看了这表明由10乘以INT,然后加入数字解决方案,但是这可能会导致整数溢出。结果 这是确保安全的或者是有这样做的更好的方法?如果我用10做乘法和加法的数字解决方案,我应该采取什么预防措施?

有帮助吗?

解决方案

最好的办法是通过10和相加的值的乘法运算。你可以做的幼稚检查像这样:

assert(digit >= 0 && digit < 10);
newValue = (oldValue * 10) + digit;
if (newValue < oldValue)
{
    // overflow
}

其他提示

要防止溢出:

if ((0 <= value) && (value <= ((MAX_INT - 9) / 10))) {
    return (value * 10) + digit;
}

在地方MAX_INT的,可以使用std::numeric_limits<typeof(value)>::max()或类似,以支持其它类型的比中间体

  assert(digit >= 0 && digit < 10);
  newvalue = 10 * oldvalue;
  if (oldvalue < 0 ) {
    newvalue -= digit;
  } else {
    newvalue += digit;
  }

  // check for overflow SGN(oldvalue) == 0 || SGN(newvalue) == SGN(oldvalue)

下面是一个更好和更防弹执行比被接受为一个答案的一个是也快:

#include <climits>
#include <cassert>

unsigned int add_digit(unsigned int val, unsigned int digit)
{
   // These should be computed at compile time and never even be given a memory location
   static const unsigned int max_no_overflow = (UINT_MAX - 9) / 10U;
   static const unsigned int max_maybe_overflow = UINT_MAX / 10U;
   static const unsigned int last_digit = UINT_MAX % 10;

   assert(digit >= 0 && digit < 10);
   if ((val > max_no_overflow) && ((val > max_maybe_overflow) || (digit > last_digit))) {
      // handle overflow
   } else {
      return val * 10 + digit;
   }
   assert(false);
}

您也应该能够使成一个内联函数这一点。溢出检查将第一次比较之后几乎总是短路。在&&后的条款只是这样你就可以(在32位的情况下,二的补码整数)添加5〜的429496729结束,但不是6。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top