为什么“long double”类型的变量产生荒谬的输出,而“float”和“double”类型工作正常?

时间:2013-05-01 00:45:34

标签: c floating-point double floating-accuracy long-double

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

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

    我认为product只是long double的“高容量”版本,它本身就是double类型的“高容量”版本!! / p>

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

  3. %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

2 个答案:

答案 0 :(得分:4)

因为您使用了错误的格式说明符将其打印出来。 floatdouble作为double传递给printf()函数(由于默认促销规则适用于它,因为它是可变参数),但是long double作为long double传递给%Lf {{1}},你必须使用{{1}}转换说明符,否则你的程序会调用未定义的行为。

答案 1 :(得分:0)

对于第二个问题:float只有23位尾数,只能保持7位精度,其余只是“垃圾”。

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

如您所见,区别在于第8个字符。 Double可以精确到大约16个字符,显然它会更精确