是否有一种安全的方法可以在整数末尾添加数字而不将其转换为字符串而不使用字符串流?
我尝试谷歌答案,大多数解决方案建议将其转换为字符串并使用字符串流,但我希望将其保留为整数以确保数据完整性并避免转换类型。
我还读了一个解决方案,建议将int乘以10,然后加上数字,但这可能会导致整数溢出
这样做是否安全或有更好的方法吗?如果我这样做乘以10并添加数字解决方案,我应该采取什么预防措施?
答案 0 :(得分:25)
最好的选择是乘以10并增加值。你可以这样做a naive check:
assert(digit >= 0 && digit < 10);
newValue = (oldValue * 10) + digit;
if (newValue < oldValue)
{
// overflow
}
答案 1 :(得分:3)
防止溢出:
if ((0 <= value) && (value <= ((MAX_INT - 9) / 10))) {
return (value * 10) + digit;
}
代替MAX_INT,您可以使用std::numeric_limits<typeof(value)>::max()
或类似内容来支持int以外的类型。
答案 2 :(得分:2)
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)
答案 3 :(得分:2)
这是一个更好,更防弹的实现,而不是被接受为快速的答案:
#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位,2的补码整数的情况下)将42添加到429496729的末尾,但不是6。