The long double

17 views
Skip to first unread message

Piotr Grochowski

unread,
Nov 4, 2022, 3:20:48 PM11/4/22
to emscripten-discuss

sizeof(long double)
16
LDBL_MANT_DIG
113

This completely throws me off since I use long double in my code expecting it to be native (for example, on Digital Mars on Windows, sizeof(long double) is 10, and LDBL_MANT_DIG is 64). And quadruple precision is not native in many computers. This certainly should be warned about in https://emscripten.org/docs/porting/guidelines/portability_guidelines.html#code-that-compiles-but-might-run-slowly . So how do I get long double to be double precision instead (sizeof(long double) being 8, and LDBL_MANT_DIG being 53)?

Thomas Lively

unread,
Nov 4, 2022, 3:27:39 PM11/4/22
to emscripte...@googlegroups.com
I don't believe there is an option to make long double 64 bits, since that would be an ABI-breaking change. If you're recompiling all your code, though, I suppose you could use a hack like using a macro to redefine `long double` to just `double`.

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/emscripten-discuss/23b05bb2-1164-4885-9eb4-cacd7d337f3dn%40googlegroups.com.

Sam Clegg

unread,
Nov 4, 2022, 5:09:10 PM11/4/22
to emscripte...@googlegroups.com
Can I ask what type of thing you are using `long double` for?      We haven't seen muck codebases that use (mostly just printf when it wants to print one).   If you are expecting it to be the same as `double` why not just use `double`?



--

Piotr Grochowski

unread,
Nov 4, 2022, 5:50:27 PM11/4/22
to emscripten-discuss
Here is an example of my usage of long double, in this case the functions have a double precision interface, but the functions not directly available in double use long double internally:


field rng(const field& x,const field& y){
    long double a = longdoublify(x);
    long double b = longdoublify(y);
    long double const m = powl(2,-64);
    return (double)(next()*m*(b-a)+a);
}

const long double tau = 6.283185307179586477l;

field funct(const field& x,const field& y){
    u16abstract a = stringify(x);
    double b = doublify(y);
    do{
        if(a==sk("abs" )) {b=fabs(b);break;}
        if(a==sk("sqrt")) {b=sqrt(b);break;}
        if(a==sk("sin" )) {b=sinl(b*(tau/360.l));break;}
        if(a==sk("cos" )) {b=cosl(b*(tau/360.l));break;}
        if(a==sk("tan" )) {b=tanl(b*(tau/360.l));break;}
        if(a==sk("asin")) {b=asinl(b)*(360.l/tau);break;}
        if(a==sk("acos")) {b=acosl(b)*(360.l/tau);break;}
        if(a==sk("atan")) {b=atanl(b)*(360.l/tau);break;}
        if(a==sk("ln"  )) {b=log(b);break;}
        if(a==sk("log" )) {b=log10(b);break;}
        if(a==sk("e ^" )) {b=exp(b);break;}
        if(a==sk("10 ^")) {b=pow(10,b);break;}
    }while(0);
    return b;
}

So, for example, on a 32-bit ARM computer, where long double is double precision, sinl(b*(tau/360.l)) is equivalent to sin(b*(6.283185307179586/360)), whereas on Windows with Digital Mars, extended precision will be used. The intent is that the intermediate computations are native. With x87, extended precision is typically more native than double precision, so it makes sense to use long double as the native type, however, when long double is unnative, internal computations can slow down the program functions.

Sam Clegg

unread,
Nov 4, 2022, 6:39:32 PM11/4/22
to emscripte...@googlegroups.com
Thanks, that makes sense.  I hadn't realized that `long double` on x87 could give you extended precision.

Unfortunately I don't think we will be able to change the default wasm ABI type for `long double` at this point.   Its possible we could make the existing clang `-mlong-double-64` flag work (maybe it does already?), but that would an ABI-breaking change so all libraries (uncluding libc) would need to be recompiled in that case.

Would it be possible to add an AVOID_LONG_DOUBLE macro to your code?  (Or I suppose using the #define trick that Thomas mentioned)?

Reply all
Reply to author
Forward
0 new messages