使用指数溢出计算最大长值

Calculating max long value using exponent overflows

我试图通过计算基数 2 的指数来计算类型 long 的最大值。

不幸的是,计算在第 61 步溢出,我不明白为什么。

long exponential(int base, int exponent)
{
    long result = (long)base;
    for (int i = 0; i < exponent; i++) {
        result *= base;
    }
    return result;
}

unsigned int sLong = sizeof(long);

long lResult = exponential(2, (sLong * 8) - 1);

lResult 是 运行 函数后的 0

奇怪的是,当我为 charshortint 执行此操作时,它工作正常。

这里的代码有一个差一错误。

考虑以下问题:exponential(10, 2) 的结果是什么?经验调试(使用printf语句)显示是1000。所以exponential计算数学表达式be+1.

long类型通常有64位。这似乎是你的情况(看到溢出发生在第 64 步左右)。看到它是一个有符号类型,它的范围(通常)是从 -263 到 263-1。即该数据类型所能表示的2的最大次方为262;如果代码尝试计算 263,则会发生溢出 (you probably want to avoid it).

因此,由于差一错误,代码将导致 exponent 大于或等于 62 的溢出。


要修复差一错误,请从 1 开始乘法:

long power_of(int base, int exponent)
{
    long result = (long)1; // 0th power of base is 1
    for (int i=0; i<exponent;i++) {
        result*=base;
    }
    return result;
}

但是,这不会消除溢出,因为long数据类型不能表示数字263。幸运的是,您可以使用 unsigned long long,它保证对于您正在进行的计算类型足够大:

unsigned long long power_of(int base, int exponent)
{
    unsigned long long result = 1ULL; // 0th power of base is 1
    for (int i=0; i<exponent;i++) {
        result*=base;
    }
    return result;
}

llu格式打印:

printf("%llu", power_of(2, 63));