Search code examples
cfloating-pointfractionsexponentlong-double

Inverting the exponent of a long double gives me an insane result


I am trying to invert the exponent of a long double.

Suppose x = 3.5e1356. I want x to be 3.5e-1356.

I have this code:

long double x = 3.5e1356L;
int exponent;
long double fraction = frexpl(x, &exponent);

// recreate number with an inverted exponent
long double newNumber =  ldexpl(fraction, -exponent);

after this code, newNumber is 1.14732677619641872902e-1357

that has nothing to do with the original number.

What am I missing?


Solution

  • Use the fact that

    a * (10^n) * (10^m) = a * 10^(n+m) 
    

    If you calculate m so that it is -2n you'll get:

    a * (10^n) * (10^-2n) = a * 10^(n+(-2n)) =  a * 10^-n
    

    In other words - just multiply the original number with 10^-2n

    I would try something like this:

    #include <stdio.h>
    #include <math.h>
    
    int main(void) {
        long double x = 8.9e-100;
        long double y = 0.0;
        int exp10;
    
        if (x != 0.0)
        {
            exp10 = log10l(fabsl(x));
            exp10 = (exp10 >= 0) ? -2*exp10 : -2*(exp10-1);
            y = x * powl(10, exp10);
        }
    
        printf("%.36Le\n", x);
        printf("%.36Le\n", y);
    
        return 0;
    }
    

    Example for 3.5 * 10^12 :

    3.5 * 10^12 * 10^-24 --> 3.5 * 10^-12