整数除法溢出 [英] Integer division overflows

查看:296
本文介绍了整数除法溢出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在考虑整数(类型为int)的溢出,而在我看来除法可能会溢出。

I have been thinking about integer (type int) overflows, and it occurs to me that division could overflow.

示例:在当前平台上,我有

Example: On my current platform, I have

INT_MIN == -INT_MAX - 1

,因此

INT_MIN < -INT_MAX

,因此

INT_MIN / -1 > -INT_MAX / -1

,因此

INT_MIN / -1 > INT_MAX.

因此,除法(INT_MIN / -1)确实溢出。

Hence, the division ( INT_MIN / -1 ) does overflow.

所以,我有两个问题:


  1. 一个人可以写什么(跨平台的)C代码来防止除法溢出(对于(有符号的)int类型)?

  1. What (cross-platform) C code could one write in order to prevent division overflows (for type (signed) int)?

什么保证(以C或C ++标准)可能有助于设计代码?

What guarantees (in C or C++ standard) might help to devise the code?






例如,如果标准保证我们拥有


For example, if the standard guarantees that we have either

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 ++标准)可能有助于设计代码?

What guarantees (in C or C++ standard) might help to devise the code?

C使用3中的1指定整数形式:符号和大小,二进制补码或二进制补码。鉴于这些形式,只有溢出除以0和 INT_MIN / -1 的补数除法。

C specifies signed integer representation as using 1 of 3 forms: sign and magnitude, two’s complement, or ones’ complement. Given these forms, only division by 0 and two’s complement division of INT_MIN/-1 may overflow.


一个人可以写什么(跨平台的)C代码以防止除法溢出(对于(有符号的)int类型)?

What (cross-platform) C code could one write in order to prevent division overflows (for type (signed) 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;
}

这篇关于整数除法溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆