これは、回答として受け入れられたものよりも優れた防弾実装であり、高速でもあります。
#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 の補数の整数の場合) 429496729 の末尾に 5 を追加できるようにするためのものですが、6 は追加できません。