0

我想要下面的程序做的就是打印所有小于 30 的正数的乘积(以指数和非指数形式)。当变量product声明为 afloat或 a时它工作正常double,但当类型为 时会产生完全荒谬(否定)的结果long double。那么请回答由此引发的这两个问题:

  1. 为什么long double产生完全荒谬(甚至负面)的结果,而float变量 double的类型product产生正确的结果?

    我有这个概念,long double它只不过是 的“高容量”版本double,它本身就是float类型的“高容量”版本!

  2. 现在对于产生正确结果的类型product,即floatdouble,为什么它们以指数形式(%e)产生相同的输出,但对于非指数形式(%f)产生明显不同的输出?


#include<stdio.h>

int main(void)
{
    int j;
    float product=1;   //Works fine
    //double product=1;  //Works fine
    //long double product=1; //Produces absurd output.
    
    
    for(j=2;j<=30;j=j+2)
    product=product*j;
    
    printf("The product of even numbers <30 is %e \n",product);
    printf("The product in non-exponential form is %f",product);
}

product作为浮点数的输出

The product of even numbers <30 is 4.284987e+16 
The product in non-exponential form is 42849875099910144.000000

product双倍输出

The product of even numbers <30 is 4.284987e+16 
The product in non-exponential form is 42849873690624000.000000

输出product只要双倍

The product of even numbers <30 is -6.078565e-192 
The product in non-exponential form is -0.000000
4

2 回答 2

4

因为您使用了错误的格式说明符来打印它。float并作为函数double传递(由于它是可变参数,因此应用了默认提升规则),但作为 传递,您必须为其使用转换说明符,否则您的程序会调用未定义的行为。doubleprintf()long doublelong double%Lf

于 2013-05-01T00:49:05.120 回答
0

对于第二个问题:float只有 24 位有效位,并且只能保持大约 6-7 位精度(真正的精度不是整数,因为计算机中的浮点类型通常使用二进制而我们人类使用十进制),其余的只是“垃圾”。

                  float error
precision: 1234567↓90ABCDEF digits
float:     42849875099910144.000000
double:    42849873690624000.000000

如您所见,差异在第 8double有 53 位有效数字,可以精确到大约 15 个十进制数字,这显然意味着它会更精确。但是如果四舍五入到第 6位(这是 %e 的默认值),那么两者都会导致 4.284987e+16,这会导致误解,即结果floatdouble相同的,即使它们不是。例如,如果您打印更多的十进制数字%.20e,那么您将看到与%f

如果您修复格式说明符long double并进行更多迭代,那么如果更精确,double则会遇到同样的问题。long double例如,如果您将代码中的限制从 30 增加到 50,那么您将得到这个

float:       5.204699e+32
             520469877396214593413323729928192.000000
double:      5.204698e+32
             520469842636666625085618390040576.000000
long double: 5.204698e+32
             520469842636666622693081088000000.000000

https://ideone.com/L6P9d6

于 2013-07-27T15:22:23.687 回答