题
是否有添加在一个整数的端部的位而不将其转换为字符串,并在不使用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。
不隶属于 StackOverflow