我试图编写一个程序,用while循环计算x^n的值:

#include <stdio.h>
#include <math.h>
int main()
{
    float x = 3, power = 1, copyx;
    int n = 22, copyn;
    copyx = x;
    copyn = n;

    while (n)
    {
        if ((n % 2) == 1)
        {
            power = power * x;
        }
        n = n / 2;
        x *= x;
    }

    printf("%g^%d = %f\n", copyx, copyn, power);
    printf("%g^%d = %f\n", copyx, copyn, pow(copyx, copyn));

    return 0;
}

直到n的值为15,我创建的函数和pow函数(math.h)的答案给出了相同的值;但是,当n的值超过15时,它开始给出不同的答案.

我不明白为什么答案不同.是我用错误的方式写的函数,还是其他原因?

推荐答案

您正在混合两种不同类型的浮点数据.pow函数使用double类型,但循环使用float类型(精度较低).

通过对xpowercopyx变量使用double类型,either可以使结果一致,通过调用powf函数(使用float类型)而不是powor可以使结果一致.

后一种调整(使用powf)给出以下输出(clang cl编译器,Windows 10,64位):

3^22 = 31381059584.000000
3^22 = 31381059584.000000

并且,将main的第一行改为double x = 3, power = 1, copyx;可以得到以下结果:

3^22 = 31381059609.000000
3^22 = 31381059609.000000

请注意,随着n的值越来越大,循环结果与使用powpowf库函数计算的值之间的差异越来越大.在我的平台上,double版本给出了相同的结果,直到值溢出范围,变成Infinity.然而,float版本在n = 55左右开始出现分歧:

3^55 = 174449198498104595772866560.000000
3^55 = 174449216944848669482418176.000000

C相关问答推荐

为什么 memcpy() 随机不复制正确的值?

为什么启用优化时 GCC 11 编译器会产生奇怪的输出?

Gnuplot 和 C - 绘制不同的符号/ colored颜色

在 C 中使用数组而不是向量

幂函数给出的答案与 C 中的 math.pow 函数不同

确定在嵌入式 C 中运行时使用哪个变量

在编译时构建静态数组

判断由大括号组成的输入字符串是否格式正确

通过默认网关地址的硬件地址而不是以太网多播地址发送多播

为什么 malloc() 被认为是库调用而不是系统调用?

为什么使用 MOV 指令将 XOR 交换优化为普通交换?