10

整数を文字列に変換せず、 stringstreams を使用せずに整数の末尾に数字を追加する安全な方法はありますか?

私はこれに対する答えをグーグルで検索しようとしましたが、ほとんどのソリューションはそれを文字列に変換して文字列ストリームを使用することを提案しましたが、データの整合性を確保し、型の変換を避けるために整数として保持したいと思います.
intに10を掛けてから数字を追加することを提案したソリューションも読みましたが、これにより整数オーバーフローが発生する可能性があります。
これを行うのは安全ですか、それともこれを行うためのより良い方法はありますか? これを 10 倍して数字の解を足すとしたら、どのような予防措置を講じるべきでしょうか?

4

4 に答える 4

26

あなたの最善の策は、10 を掛けて値を加算することです。次のような単純なチェックを行うことができます。

assert(digit >= 0 && digit < 10);
newValue = (oldValue * 10) + digit;
if (newValue < oldValue)
{
    // overflow
}
于 2009-05-26T19:32:46.220 に答える
3

オーバーフローを防ぐには:

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

MAX_INT の代わりに、std::numeric_limits<typeof(value)>::max()または類似のものを使用して、int 以外の型をサポートできます。

于 2009-05-26T20:23:47.367 に答える
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 の補数の整数の場合) 429496729 の末尾に 5 を追加できるようにするためのものですが、6 は追加できません。

于 2010-01-28T05:24:02.303 に答える
2
  assert (桁 >= 0 && 桁 < 10);
  newvalue = 10 * oldvalue;
  もし (古い値 < 0 ) {
    newvalue -= 数字;
  } そうしないと {
    newvalue += 数字;
  }

  // オーバーフローをチェック SGN(oldvalue) == 0 || SGN(新しい値) == SGN(古い値)
于 2009-05-26T20:35:26.593 に答える