Re: Floats, doubles C and MSVC

Discussion in 'C Programming' started by Andrew Reilly, Oct 14, 2004.

  1. On Wed, 13 Oct 2004 23:18:00 +0100, John Dallman wrote:
    > In article <-users.org>,
    > -users.org (Andrew Reilly) wrote:
    >
    >> I've discovered an unexpected problem with some signal processing code
    >> that I've been testing on various C platforms. I had been developing
    >> with GCC under FreeBSD and MacOSX, and didn't have any problems.
    >> When some of my colleagues ran it under Windows (compiled by MSVC),

    >
    > Which version of MSVC? 4.0 or later are OK; they set up the x87 FPU to use
    > honest 64-bit doubles, rather than the 80-bit kind. I don't know about
    > MSVC2.0, but MSVC 1.x uses 80-bit arithmetic


    MSVC is version 6.

    > And what flags? Try adding the "/Op" flag for "Improved floating-point
    > consistency". That often fixes these problems; the default settings are a
    > bit wild-and-wooly.


    Thanks for the suggestion. I'll pass it on to my MSVC-constrained
    colleagues.

    The issue seems (to me) to devolve into: "under what circumstances, in C,
    can one rely on cast from "double" to "float" to "take", when the original
    double value is still in scope?" There seem to be some weasel words in
    the C (C++ only?) standard about compilers being allowed to "be
    represented in greater precision and range than that required by the type".

    Hmm. Looking at that again, that post again (the first one by Ken Hagen),
    it only refers to operands and results of expressions. So values passed
    between statements, in variables, must presumably have the type cast
    applied to them, even if they are subsequently manipulated in double
    precision again?

    I.e.:

    double get_LSBs(double d) { return d - (float)d; }

    might legitimately always return zero, because (float)d is an operand in a
    floating point expression and may actually be used as just d, but

    double get_LSBs(double d) { float f = (float) d; return d - f; }

    should be able to be relied upon to return a value derived from the LSBs
    of d. Right?

    If that's the case, then MSVC-6 is definitely doing the wrong thing.

    Could my previous idea of doing the cast with a separate function:
    float float_me(double d) { return (float)d; }
    even be expected to work, given that the x86-32 ABIs seem to return
    floating point results in TOS of the x87?

    Cheers,

    --
    Andrew
     
    Andrew Reilly, Oct 14, 2004
    #1
    1. Advertising

  2. Andrew Reilly

    jacob navia Guest

    This was discussed in comp.std.c some time ago.

    The standard implies that casts from double to float and the
    other way around should be actually done, i.e. the precision should
    be shed and the number, even if *represented* in
    greter precision should be converted to 24 bit precision.

    lcc-win32 implements this by storing the long double
    format used internally into memory, then re-reading it again.

    The same happens with the conversion of long double to
    double and the other way around
     
    jacob navia, Oct 14, 2004
    #2
    1. Advertising

  3. Andrew Reilly

    Tim Prince Guest

    "Andrew Reilly" <-users.org> wrote in message
    news:p-users.org...
    > On Wed, 13 Oct 2004 23:18:00 +0100, John Dallman wrote:
    > > In article <-users.org>,
    > > -users.org (Andrew Reilly) wrote:
    > >
    > >> I've discovered an unexpected problem with some signal processing code
    > >> that I've been testing on various C platforms. I had been developing
    > >> with GCC under FreeBSD and MacOSX, and didn't have any problems.
    > >> When some of my colleagues ran it under Windows (compiled by MSVC),

    > >
    > > Which version of MSVC? 4.0 or later are OK; they set up the x87 FPU to

    use
    > > honest 64-bit doubles, rather than the 80-bit kind. I don't know about
    > > MSVC2.0, but MSVC 1.x uses 80-bit arithmetic

    >
    > MSVC is version 6.
    >
    > > And what flags? Try adding the "/Op" flag for "Improved floating-point
    > > consistency". That often fixes these problems; the default settings are

    a
    > > bit wild-and-wooly.

    >

    That's correct. /Op includes the same effect as you would see in gcc
    with -ffloat-store.
    With x87 code, performing a true conversion from double to float and back to
    double, as required for further arithmetic, is extremely time-consuming. It
    requires at least that the entire cache line be updated at all levels of
    cache, presumably with "joined at the bus" acceleration to get your operand
    back prior to finishing those updates. This is one of the reasons why all
    CPUs in those families from P-III and Athlon on provide SSE floating point
    instructions. MSVC6 was probably the last widely used compiler which didn't
    provide an option to use SSE at least for scalar instructions.
     
    Tim Prince, Oct 14, 2004
    #3
    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. dan
    Replies:
    1
    Views:
    2,364
    Jack Klein
    Nov 26, 2003
  2. J.K. Becker
    Replies:
    43
    Views:
    1,047
  3. SpreadTooThin
    Replies:
    7
    Views:
    445
    Diez B. Roggisch
    Sep 16, 2006
  4. Replies:
    14
    Views:
    572
    August Karlstrom
    May 26, 2005
  5. Pavel
    Replies:
    13
    Views:
    950
    Richard Herring
    Mar 14, 2008
Loading...

Share This Page