Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 10 Apr 2012 10:34:28 -0600
From:      Ian Lepore <freebsd@damnhippie.dyndns.org>
To:        freebsd-arm@freebsd.org
Subject:   Re: Trouble with long double support on arm
Message-ID:  <1334075668.1082.93.camel@revolution.hippie.lan>
In-Reply-To: <1334002103.1082.84.camel@revolution.hippie.lan>
References:  <1334002103.1082.84.camel@revolution.hippie.lan>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 2012-04-09 at 14:08 -0600, Ian Lepore wrote:
> A collegue at work has just run into trouble with printf() and long
> double with softfloat on arm.  It looks like C++ stream output has the
> same problem.  It appears that the math itself works correctly, but
> attempting to print the value gives wrong output.
> 
> We're pretty sure that this is a problem only with coverting long double
> values to ascii.  In all other ways, long double seems to be properly
> handled the same as double (which you'd expect given the defines in
> float.h for arm).  We use long double types in a few places in our
> products where wrong results would lead to in-your-face wrong behavior,
> and we've never seen anything like that.  This was noticed in some debug
> logging which is normally disabled but he happened to be looking at it
> closely today.
> 
> This simple program:
> 
>         #include <float.h>
>         #include <stdio.h>
>         #include <iostream>
>         
>         int main(int argc, char **argv)
>         {
>             printf("Long Double Test\n");
>             printf("sizeof(double): %d\n", sizeof(double));
>             printf("sizeof(long double): %d\n", sizeof(long double));
>         
>             double f = 9999999.898991832509637;
>             long double lf = f;
>         
>             printf("double as double: %f\n", f);
>             printf("long double as double: %f\n", lf);
>             printf("double as long double: %Lf\n", f);
>             printf("long double as long double: %Lf\n", lf);
>             std::cout << "long double via cout " << lf << std::endl;
>             printf("double as hex double: %A\n", f);
>             printf("long double as hex long double: %LA\n", lf);
>         
>             return 0;
>         }
>         
> Produces this output:
>         
>         # /usr/tsc/bin/testsimple 
>         Long Double Test
>         sizeof(double): 8
>         sizeof(long double): 8
>         double as double: 9999999.898992
>         long double as double: 9999999.898992
>         double as long double: 1611391.898991
>         long double as long double: 1611391.898991
>         long double via cout 1.61139e+06
>         double as hex double: 0X1.312CFFCC48A85P+23
>         long double as hex long double: 0X1.312CFFCC48A85P+23
>         
> I get the same output on 8.2 and 9.0.  You'd expect the "double as long
> double" case to be wrong, but it seems like it might be a clue that the
> "long double as long double" case is the same value.
> 
> I pointed him at the twisty maze of lib/libc, lib/msun, and contrib/gcc,
> and he's currently trying to track down which function actually gets
> called to handle %Lf, but I figured I'd ask here as well in case
> somebody has already fought this battle and knows what's going on.
> 
> -- Ian

A followup to help anyone who stumbles across this thread in the
future...

This problem was identified a couple months ago by Maks Verver, and the
fix was commited in r230188.

-- Ian





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1334075668.1082.93.camel>