gpt4 book ai didi

c - 检测并防止 C 中 unsigned long 的溢出

转载 作者:行者123 更新时间:2023-12-04 09:59:38 26 4
gpt4 key购买 nike

我的代码中有一些行来检查结果值是否溢出(通过将其与之前的迭代进行比较),以及输入值是否太大。这适用于某些值,但不适用于增量大到不仅溢出,而且溢出的结果值大于前一次迭代的值。例如,它触发 18446744073709551616 ( MAX_ULONG + 1 ),但不适用于 184467440737095516150 ( MAX_ULONG * 10 )。我该如何解决这个问题?代码如下:

unsigned long result = 0;
unsigned long overflowCheck = 0;
int power = 0;

for (int i = (strlen(input) - 1); i >= 0; i--) {
if ((input[i] > ('0' - 1)) && (input[i] < ('9' + 1))) {
result += (input[i] - '0') * (unsigned long)pow(iBase, power++);
} else {
printf("Invalid input string.");
valid = 0;
return -1;
}
if (result < overflowCheck) {
printf("Input value too large.");
valid = 0;
return -1;
}
overflowCheck = result;
}
return result;

最佳答案

您的代码中有多个问题:

  • 你不应该使用 pow执行整数运算:输入 double可能比类型 unsigned long 具有更少的值位(例如在 64 位 linux 上,double 有 53 个值位,而 unsigned long 有 64 个)。将当前值乘以 iBase 更简单并为解析的每个新数字添加数字值。
  • 更容易检测潜在的溢出 之前 值相乘或相加。

  • 这是一个修改后的版本:

    #include <errno.h>
    #include <limits.h>

    unsigned long atoul(const char *input, unsigned int iBase) {
    if (iBase < 2 || iBase > 36) {
    errno = EINVAL;
    return 0;
    }
    unsigned long result = 0;
    unsigned long maxval = ULONG_MAX / iBase;
    int maxdigit = ULONG_MAX % iBase;

    for (;;) {
    int c = *input++;
    int digit;
    if (c >= '0' && c <= '9') {
    digit = c - '0';
    } else
    if (c >= 'A' && c <= 'Z') {
    digit = c - 'A' + 10;
    } else
    if (c >= 'a' && c <= 'z') {
    digit = c - 'a' + 10;
    } else {
    break;
    }
    if (digit >= iBase)
    break;
    if (result > maxval || (result == maxval && digit > maxdigit) {
    /* overflow detected */
    errno = ERANGE;
    return ULONG_MAX;
    }
    result = result * iBase + digit;
    }
    return result;
    }

    关于c - 检测并防止 C 中 unsigned long 的溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61857378/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com