[semi OT] - Lack of long double implementation in VS

Discussion in 'C Programming' started by Bubba, Oct 23, 2011.

  1. Bubba

    Bubba Guest

    Greetings to all!

    I will begin with a humble apology for posting such "impure" article, but
    I was wandering - shouldn't data types be defined by architecture, and not
    by compiler? I trust the answer is yes, but having such "by design" flaw
    by Microsoft just escapes me.

    To my surprise, I found out today (on harder way) that even in VS 2010

    {
    long double x;
    size_t s = sizeof(x):
    }

    gives '8', while gcc returns '16' (as expected).

    Did some homework and read articles but could not find a sane reason for
    such implementation (due to more than 20 years of 80 bit FPU in x86
    CPU's).

    Is anyone acquainted more detailed about this issue?

    Furthermore, I was shocked to find out that Windows calculator couldn't
    calculate properly subtraction sqrt(x) and real square root of that number
    (sqrt(4) - 2, sqrt(16) - 4...).

    Yes, I am aware of IEEE 754, but I couldn't implement that one even in
    GMP:

    bubba@korea:~$ cat b.c
    #include <gmp.h>

    int main (int argc, char *argv[]) {
    mpf_t sq_me, sq_out, test, sub;
    mpf_set_default_prec (1024);
    mpf_init(sq_me);
    mpf_init(sq_out);
    mpf_init(test);
    mpf_init(sub);
    mpf_set_str (sq_me, argv[1], 10);
    mpf_set_str (sub, "2", 10);

    mpf_sqrt(sq_out, sq_me);
    mpf_sub(test,sq_out,sub);

    gmp_printf ("Input: %Ff\n\n", sq_me);
    gmp_printf ("Square root: %.1000Ff\n\n", sq_out);
    gmp_printf ("Subtraction: %.1000Ff\n\n", test);

    return 0;
    }

    bubba@korea:~$ gcc -g -Wall -pedantic -ansi -O3 b.c -lgmp
    bubba@korea:~$ ./a.out 4
    Input: 4.000000

    Square root:
    2.000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    0000000000000000000000000000000000000000

    Subtraction:
    0.000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000000000000000000000000000000000000000000000
    0000000000000000000000000000000000000000

    I tried to produce similar error in gcc but failed. Does anyone know who
    is it implemented to make such errors? I guess it is C, but can't figure
    out how come they haven't fixed it since Windows XP...

    --
    "If you lie to the compiler,
    it will get its revenge."
    Henry Spencer
    2.718281828459045235360287471352662497757247093699959574966967627.com
     
    Bubba, Oct 23, 2011
    #1
    1. Advertising

  2. Bubba <> writes:
    > I will begin with a humble apology for posting such "impure" article, but
    > I was wandering - shouldn't data types be defined by architecture, and not
    > by compiler? I trust the answer is yes, but having such "by design" flaw
    > by Microsoft just escapes me.


    Data types are defined by the compiler. The characteristics of the
    underlying architecture are certainly an important factor for the
    compiler authors to consider, but not the only one.

    > To my surprise, I found out today (on harder way) that even in VS 2010
    >
    > {
    > long double x;
    > size_t s = sizeof(x):
    > }
    >
    > gives '8', while gcc returns '16' (as expected).


    Why did you expect 16?

    The standard requires float to support at least 6 decimal digits, double
    to support at least 10, and long double to support at least 10. In
    fact, *all* the minimal requirements for long double are the same as
    those for double. The set of values of type double must be a subset of
    the set of values of type long double, but they're allowed to be
    identical. (Even so, they're distinct types.)

    > Did some homework and read articles but could not find a sane reason for
    > such implementation (due to more than 20 years of 80 bit FPU in x86
    > CPU's).
    >
    > Is anyone acquainted more detailed about this issue?


    Microsoft's decision to make long double the same size as double is
    permitted by the C standard.

    Whether they *should* have made it bigger is another question, and why
    they didn't is yet another. I don't have an answer to that last one.

    > Furthermore, I was shocked to find out that Windows calculator couldn't
    > calculate properly subtraction sqrt(x) and real square root of that number
    > (sqrt(4) - 2, sqrt(16) - 4...).


    I have no idea how the Windows calculator is implemented; questions
    about it are likely not about C.

    [...]

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Oct 23, 2011
    #2
    1. Advertising

  3. Bubba

    Eric Sosman Guest

    On 10/23/2011 4:23 PM, Bubba wrote:
    > Greetings to all!
    >
    > I will begin with a humble apology for posting such "impure" article, but
    > I was wandering - shouldn't data types be defined by architecture, and not
    > by compiler? I trust the answer is yes, but having such "by design" flaw
    > by Microsoft just escapes me.


    C's data types are defined by the language Standard, but the
    definitions are purposely loose to permit adaptability to a range
    of hardware. The C implementation is expected to choose "something
    suitable" for each data type, as long as it meets the requirements
    of the Standard.

    On a particular system, some of the mappings between C types and
    native types will be fairly obvious. Others, though, will be less
    than obvious, and different C implementations may choose differently.
    For example, consider 64-bit machines, which (commonly) provide four
    native integer widths of 8, 16, 32, and 64 bits. There's an obvious
    way to map these to the four integer widths offered by C90: Just call
    them char, short, int, and long, in that order. Digital Equipment
    Corporation did exactly that -- see how successful they've been? ;)

    (It would be something of a stretch to blame DEC's demise on their
    C implementation, but my point is that the "obvious" mapping between
    language types and native types is not necessarily the "right" one.)

    > To my surprise, I found out today (on harder way) that even in VS 2010
    >
    > {
    > long double x;
    > size_t s = sizeof(x):
    > }
    >
    > gives '8', while gcc returns '16' (as expected).
    >
    > Did some homework and read articles but could not find a sane reason for
    > such implementation (due to more than 20 years of 80 bit FPU in x86
    > CPU's).
    >
    > Is anyone acquainted more detailed about this issue?


    It appears Microsoft chose to map both long double and double to
    the same underlying native type, just as they map both long and int
    to a single underlying type. Why? Dunno; you'll have to ask Redmond.
    Pure speculation: Maybe there were interoperability issues with other
    languages, or maybe deadline pressure was too fierce to allow time
    for writing a third suite of math library functions. Ask Redmond.

    > Furthermore, I was shocked to find out that Windows calculator couldn't
    > calculate properly subtraction sqrt(x) and real square root of that number
    > (sqrt(4) - 2, sqrt(16) - 4...).


    Is the calculator implemented in C, and does it use C's arithmetic
    types? It's own Help suggests not: It claims 32-digit precision (which
    would be more than 106 bits), and mentions that rational numbers are
    stored as fractions rather than as floating-point. For me, sqrt(4)-2
    gives about -8.2e-39, suggesting that even when floating-point is used
    (assuming sqrt delivers an F-P result), the precision is nearly 128
    bits. It seems unlikely that the calculator uses an unaided native
    format.

    --
    Eric Sosman
    d
     
    Eric Sosman, Oct 23, 2011
    #3
  4. Bubba

    Kaz Kylheku Guest

    On 2011-10-23, Bubba <> wrote:
    > Greetings to all!
    >
    > I will begin with a humble apology for posting such "impure" article, but
    > I was wandering - shouldn't data types be defined by architecture, and not
    > by compiler? I trust the answer is yes, but having such "by design" flaw
    > by Microsoft just escapes me.


    Note that the Microsoft toolchain is free (as in beer).

    They have no incentive for improving it because they pretty much wiped out the
    non-free, non-open-source competitors, and probably don't care about earning a
    bigger slice of zero.

    > gives '8', while gcc returns '16' (as expected).


    If you think that GCC has better numeric support, then use it.

    You can use gcc for compiling Windows programs, such that they
    do not depend on any special run-time libraries or any Unix-like
    environment: www.mingw.org.
     
    Kaz Kylheku, Oct 24, 2011
    #4
  5. Kaz Kylheku <> writes:
    [...]
    > If you think that GCC has better numeric support, then use it.
    >
    > You can use gcc for compiling Windows programs, such that they
    > do not depend on any special run-time libraries or any Unix-like
    > environment: www.mingw.org.


    Yes, but MinGW's compiler (gcc) has 12-byte long double, but uses
    Microsoft's runtime library, which assumes 8-byte long double.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Oct 24, 2011
    #5
  6. Re: - Lack of long double implementation in VS

    On Oct 23, 9:23 pm, Bubba <> wrote:

    <snip>

    > [...] shouldn't data types be defined by architecture, and not
    > by compiler?


    no.


    > I trust the answer is yes,


    but why? It would seem sane to have architecture have an influence on
    data type definitions but i don't see why it would dictate it. Who
    gets to decide what the "correct" data type implementation is for each
    architecture? Intel?

    <snip>

    > Furthermore, I was shocked to find out that Windows calculator couldn't
    > calculate properly subtraction sqrt(x) and real square root of that number
    > (sqrt(4) - 2, sqrt(16) - 4...).


    sqrt(16) - 4 is about -5e-38.
    Seems pretty good to me!


    <snip>
     
    Nick Keighley, Oct 24, 2011
    #6
  7. Bubba

    jacob navia Guest

    Re: - Lack of long double implementation in VS

    Le 24/10/11 19:15, christian.bau a écrit :
    > On Oct 24, 4:30 am, Robert Wessel<> wrote:
    >
    >> But this was a surprise to many, circa *1993*, since their 16 bit
    >> compilers did support 80 bit long doubles. And, FWIW, sizeof(long
    >> double) was 10 on the MS 16-bit compilers, not 16, as was common on
    >> x86 *nix.

    >
    > I have no idea where this decision that 80 bit long double = 10 byte
    > came from. The hardware implementation on a modern Intel processor
    > reads 10 bytes and writes 10 bytes (so a 16 byte long double is
    > actually 80 value bits and 48 bits of rubbish) and doesn't care about
    > alignment. So having 16 bytes just adds 60 percent more size to any
    > long double data for no gain.


    Under intel 64 the stack has to be aligned to a 8 byte boundary. Pushing
    or storing any long double variable would need anyway 16 bytes. Besides,
    the processor reads more efficiently if the data is aligned to a 16 byte
    boundary.

    Many considerations like this make alignment to 16 bytes impossible to
    avoid. This makes actually waste a lot of memory like the 64 bit
    pointers where in many cases only 16 would be actually needed or at most
    32.

    jacob
     
    jacob navia, Oct 24, 2011
    #7
  8. Bubba

    Phil Carmody Guest

    Kaz Kylheku <> writes:
    > On 2011-10-23, Bubba <> wrote:
    > > Greetings to all!
    > >
    > > I will begin with a humble apology for posting such "impure" article, but
    > > I was wandering - shouldn't data types be defined by architecture, and not
    > > by compiler? I trust the answer is yes, but having such "by design" flaw
    > > by Microsoft just escapes me.

    >
    > Note that the Microsoft toolchain is free (as in beer).
    >
    > They have no incentive for improving it because they pretty much wiped out the
    > non-free, non-open-source competitors, and probably don't care about earning a
    > bigger slice of zero.
    >
    > > gives '8', while gcc returns '16' (as expected).

    >
    > If you think that GCC has better numeric support, then use it.
    >
    > You can use gcc for compiling Windows programs, such that they
    > do not depend on any special run-time libraries or any Unix-like
    > environment: www.mingw.org.


    It's nearly a decade since I touched a windows machine, but I seem
    to remember that the "portable" code I was writing, and compiling
    using mingw, suffered from an inability to understand some of the
    printf type specifiers (almost certainly in the long long direction).
    when run on windows. Ugly macro mess ensued.

    Phil
    --
    Unix is simple. It just takes a genius to understand its simplicity
    -- Dennis Ritchie (1941-2011), Unix Co-Creator
     
    Phil Carmody, Oct 26, 2011
    #8
  9. Phil Carmody <> writes:
    [...]
    > It's nearly a decade since I touched a windows machine, but I seem
    > to remember that the "portable" code I was writing, and compiling
    > using mingw, suffered from an inability to understand some of the
    > printf type specifiers (almost certainly in the long long direction).
    > when run on windows. Ugly macro mess ensued.


    That's because MinGW uses gcc as its compiler and the Microsoft
    runtime library as its library. That works for most things,
    but they differ on the representation of long double. (A quick
    experiment indicates that long long isn't a problem.)

    This isn't a bug in gcc or in Microsoft's runtime; it's a bug in
    MinGW's integration of them.

    (I'd think it would be possible to configure gcc to use 64 bits for long
    double, which would result in a consistent implementation. Perhaps the
    MinGW folks thought the advantage of greater precision was more
    important than the drawback of not being able to print long double
    values.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Oct 26, 2011
    #9
  10. Re: - Lack of long double implementation in VS

    "christian.bau" <> wrote:
    > On the stack it is no problem. And in a struct, padding can be added
    > when needed. The problem is large arrays of long double, where lets
    > say a 3 Megabyte cache only holds 196,000 long doubles when it could
    > hold 314,000. If you have an array of a million long doubles, the
    > processor will read it a lot faster if each long double is 10 byte,
    > with 10 byte alignment, than 16 byte.


    A size optimization may be a performance optimization on some
    datasets, but, it may also be a pessimization on other datasets
    (maybe for an array of 10 long double values).

    No choice is better in all cases, but, the implementation
    developer has to make a choice.

    --
    André Gillibert
     
    André Gillibert, Oct 27, 2011
    #10
  11. Bubba

    jacob navia Guest

    Re: - Lack of long double implementation in VS

    Le 27/10/11 16:28, André Gillibert a écrit :
    > "christian.bau"<> wrote:
    >> On the stack it is no problem. And in a struct, padding can be added
    >> when needed. The problem is large arrays of long double, where lets
    >> say a 3 Megabyte cache only holds 196,000 long doubles when it could
    >> hold 314,000. If you have an array of a million long doubles, the
    >> processor will read it a lot faster if each long double is 10 byte,
    >> with 10 byte alignment, than 16 byte.

    >
    > A size optimization may be a performance optimization on some
    > datasets, but, it may also be a pessimization on other datasets
    > (maybe for an array of 10 long double values).
    >
    > No choice is better in all cases, but, the implementation
    > developer has to make a choice.
    >


    Or,

    long double table[SIZE] __attribute__(packed);

    If we had a way of incorporating a directive into the
    language that would allow the compiler topack those.
     
    jacob navia, Oct 27, 2011
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ferran
    Replies:
    9
    Views:
    3,121
    Kevin Goodsell
    Apr 12, 2004
  2. JKop
    Replies:
    4
    Views:
    16,574
  3. Sydex
    Replies:
    12
    Views:
    6,658
    Victor Bazarov
    Feb 17, 2005
  4. James Stroud

    py2app semi-standalone semi-works

    James Stroud, Oct 4, 2006, in forum: Python
    Replies:
    2
    Views:
    746
    James Stroud
    Oct 4, 2006
  5. Daniel Rudy

    unsigned long long int to long double

    Daniel Rudy, Sep 19, 2005, in forum: C Programming
    Replies:
    5
    Views:
    1,248
    Peter Shaggy Haywood
    Sep 20, 2005
Loading...

Share This Page