c - 累计和溢出

标签 c overflow

假设我要加 1+11+111....加 n 次。 很明显,从n的某个值开始,累计和可能会溢出。

假设我使用以下非常简单的函数来计算上面的总和:

int calcSum(int num)
{
    int sum = 0, sequnt = 1, i;

    for (i = 0; i < num; i++)
    {
        sum += sequnt;
        sequnt = (sequnt * 10) + 1;
    }

    return sum;
}

我想为该函数添加溢出检查。

我试图在这里获得一些帮助 How to check if a number overflows an 'int'

但我不得不承认它让我感到困惑,我仍然发现在我的任务中实现它有一些困难。

如有任何帮助,我们将不胜感激。

最佳答案

由于 2 个加法或乘法中的任何一个都大致是溢出候选者,调用一个安全的 overflow checker对于每个。在 <limits.h> 中使用常量指导范围检查。

#include <limits.h>
int is_undefined_add(int a, int b) {
  return (a < 0) ? (b < INT_MIN - a) : (b > INT_MAX - a);
}

int is_undefined_mult(int a, int b) {
  if (a > 0) {
    if (b > 0) {
      return a > INT_MAX / b;       // a positive, b positive
    }
    return b < INT_MIN / a;         // a positive, b not positive
  }
  if (b > 0) {
    return a < INT_MIN / b;         // a not positive, b positive
  }
  return a != 0 && b < INT_MAX / a; // a not positive, b not positive
}

int calcSum(int num) {
  int sum = 0, sequnt = 1, i;

  for (i = 0; i < num; i++) {
    if (is_undefined_add(sum, sequnt) Handle_Overflow();
    sum += sequnt;

    if (is_undefined_mult(sequnt, 10) Handle_Overflow();
    sequnt *= 10;

    if (is_undefined_add(sequnt, 1) Handle_Overflow();
    sequnt++;
  }

  return sum;
}

is_undefined_add()is_undefined_mult()适用于 int a, int b 的所有组合.

关于c - 累计和溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51713460/

相关文章:

c - 带 c 的 socket 和 fork

c - 为什么Linux内核中没有wait_event_..._irqsave()函数或宏?

css - 为什么 overflow 与 z-index 交互?

html - 使用溢出自动并排 float 文本

css - 以父元素为位置 : relative and overlow-y:auto 弹出元素

c - 初始化匿名结构的位域

Cilk++ cilkexample.c = stderr 中的 200 行

c - gdb : address range mappings

css - 文字不换行

html - 文本溢出给出不需要的底部填充