簡體   English   中英

整數除法溢出

[英]Integer division overflows

問題

我一直在考慮整數(類型int)溢出,並且我發現分裂可能溢出。

示例 :在我當前的平台上,我有

INT_MIN == -INT_MAX - 1

因此

INT_MIN < -INT_MAX

因此

INT_MIN / -1 > -INT_MAX / -1

因此

INT_MIN / -1 > INT_MAX.

因此,除法(INT_MIN / -1)確實溢出。


問題

所以,我有兩個問題:

  1. 可以編寫什么(跨平台)C代碼以防止除法溢出(對於類型(帶符號)int)?

  2. 什么保證(在C或C ++標准中)可能有助於設計代碼?


例如,如果標准保證我們有

INT_MIN == -INT_MAX - 1

要么

INT_MIN == -INT_MAX,

然后出現以下代碼以防止溢出。

#include <limits.h>

/*
      Try to divide integer op1 by op2.
      Return
        0 (success) or
        1 (possibly overflow prevented).
      In case of success, write the quotient to res.
*/

int safe_int_div(int * res, int op1, int op2) {

  /*   assert(res != NULL);   */
  /*   assert(op2 != 0);      */

  if ( op1 == INT_MIN && op2 == -1 )  {
    return 1;
  }
  *res = op1 / op2;
  return 0;
}

什么保證(在C或C ++標准中)可能有助於設計代碼?

C將有符號整數表示指定為使用3種形式中的1種:符號和幅度,2的補碼或1的補碼。 給定這些形式,只有0和2的INT_MIN/-1的補碼除法可能溢出。

可以編寫什么(跨平台)C代碼以防止除法溢出(對於類型(帶符號)int)?

int safe_int_div(int * res, int op1, int op2) {
  if (op2 == 0) {
    return 1;
  }
  // 2's complement detection
  #if (INT_MIN != -INT_MAX) 
    if (op1 == INT_MIN && op2 == -1)  {
      return 1;
    }
  #endif
  *res = op1 / op2;
  return 0;
}

1)與C中的任何其他操作一樣,應用程序必須確保:

  • 用於計算本身的類型足夠大,並且
  • 存儲結果的變量類型足夠大。

確保這一點的方法是在操作之前設置每個操作數的大小限制。 適合的限制取決於算法和變量的目的。

2)如果你使用C標准的stdint.h,你可以保證變量有多大,便攜。 在編寫可移植代碼時,不應該使用int

對於寫入安全除法例程的情況,它將采用32位整數作為參數,然后對64位整數執行計算並將結果返回為32位整數。

#include <stdint.h>
#include <stdbool.h>

/*
      Try to divide integer op1 by op2.
      Return
        true (success) or
        false (possibly overflow prevented).
      In case of success, write the quotient to res.
      In case of failure, res remains untouched.
*/

bool safe_int_div (int32_t* res, int32_t op1, int32_t op2) {

  if(op2 == 0)
    return false;

  int64_t res64 = (int64_t)op1 / (int64_t)op2;

  if(res64 > INT32_MAX || res64 < INT32_MIN)
    return false;

  *res = (int32_t)res64_t;

  return true;
}

如果需要進一步了解除法失敗的原因,請用枚舉替換bool。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM