سؤال

هل هناك طريقة آمنة لإضافة أرقام في نهاية عدد صحيح دون تحويلها إلى سلسلة ودون استخدام Stringstreams؟

حاولت google الإجابة عن هذا والحلول التي اقترحت معظم الحلول تحويلها إلى سلسلة واستخدام stringstream ولكن أود الاحتفاظ بها كعدد صحيح لضمان تكامل البيانات وتجنب تحويل الأنواع.
قرأت أيضا حل اقترح مضاعفة INT بنسبة 10 ثم إضافة الرقم، ولكن هذا قد يتسبب في تجاوز عدد صحيح.
هل هذا آمن للقيام به أو هل هناك طريقة أفضل للقيام بذلك؟ وإذا قمت بذلك مضاعفة بنسبة 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() أو ما شابه ذلك، لدعم أنواع أخرى غير int.

 تأكيد (أرقام> = 0 && رقم <10)؛ newvalue = 10 * oldvalue؛ إذا كان (uldvalue <0) {newvalue - = رقم؛ } آخر {newvalue + = رقم؛ } // تحقق من تجاوز 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