Search code examples
cfloating-pointdoublefloating-accuracylong-double

Why is "long double" type of a variable producing absurd output while "float" and "double" type works fine?


All I want the following program to do is to print the product of all positive numbers less than 30 (in both exponential and non-exponential forms). It works fine when the variable product is declared as a float or a double,but produces totally absurd (negative) result when the type is long double. So please answer these two questions arising from it:

  1. Why is long double producing totally absurd (even negative) results while float and double types for the variable product producing correct results?

    I have this notion that long double is nothing but a "high-capacity" version of double, which is itself a "high-capacity" version of float type !!

  2. Now as of the types that are producing the correct result for product, ie float and double, why do they produce the same output in exponential form (%e) but noticeably different output for non-exponential form (%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);
}

Output for product as float

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

Output for product as double

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

Output for product as long double

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

Solution

  • Because you're using the wrong format specifier to print it out. float and double are passed as double to the printf() function (due to default promotion rules applying to it since it's variadic), but long double is passed as long double, and you have to use the %Lf conversion specifier for it, else your program invokes undefined behavior.