GCC Wikia
Advertisement

このページを編集する際は,編集に関する方針に従ってください.[]

概要[]

引数[]

  • cpp_num num
  • int digit
  • int base
  • size_t precision

実装[]

396 /* Append DIGIT to NUM, a number of PRECISION bits being read in base BASE.  */
397 static cpp_num
398 append_digit (cpp_num num, int digit, int base, size_t precision)
399 {
400   cpp_num result;
401   unsigned int shift = 3 + (base == 16);
402   bool overflow;
403   cpp_num_part add_high, add_low;
404 

  • 8倍か16倍する
    • 基数の処理

405   /* Multiply by 8 or 16.  Catching this overflow here means we don't
406      need to worry about add_high overflowing.  */
407   overflow = !!(num.high >> (PART_PRECISION - shift));
408   result.high = num.high << shift;
409   result.low = num.low << shift;
410   result.high |= num.low >> (PART_PRECISION - shift);
411   result.unsignedp = num.unsignedp;
412 

  • 基数が10の場合はnumを直接処理せずにadd_low, add_highを経由する

413   if (base == 10)
414     {
415       add_low = num.low << 1;
416       add_high = (num.high << 1) + (num.low >> (PART_PRECISION - 1));
417     }
418   else
419     add_high = add_low = 0;
420 

  • 加える値の桁上がりの処理

421   if (add_low + digit < add_low)
422     add_high++;
423   add_low += digit;
424 

  • 加算後桁上がりの処理

425   if (result.low + add_low < result.low)
426     add_high++;

  • オーバーフローのチェック

427   if (result.high + add_high < result.high)
428     overflow = true;
429 
430   result.low += add_low;
431   result.high += add_high;
432   result.overflow = overflow;
433 

  • lowとhighをフルに使わない場合ここでオーバーフローのチェック
    • 使わない領域をクリアした数値と元の数値が異なっていればオーバーフロー発生

434   /* The above code catches overflow of a cpp_num type.  This catches
435      overflow of the (possibly shorter) target precision.  */
436   num.low = result.low;
437   num.high = result.high;
438   result = num_trim (result, precision);
439   if (!num_eq (result, num))
440     result.overflow = true;
441 
442   return result;
443 }



リンク元

Advertisement