public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: "Ross Smith" <ross.s@ihug.co.nz>
To: <egcs@egcs.cygnus.com>
Subject: Re: Rounding errors using doubles?
Date: Thu, 18 Mar 1999 17:43:00 -0000	[thread overview]
Message-ID: <002d01be71aa$30d420e0$a8a11dcb@animal.ihug.co.nz> (raw)

From: Sam Lantinga <slouken@devolution.com>
>
>I have to thank everyone here on this list for your responsiveness.
>The problem was caused by unexpected values in code using doubles
>that was ported from Windows.  Apparently, by default, Windows uses 
>53 bits of precision for it's double operations.  Linux uses 64 bits.
>
>Since the code relies on the exact behavior of doubles quite extensively,
>we are setting the precision of the FPU to 53 bits using the fldcw
>instruction. :)
>
>BTW, does anyone know what precision is used on the PPC and Alpha
>architectures?

It's not really a difference between operating systems or (to a first
approximation) CPUs.

There's a standard called IEC 559 (formerly IEEE 754), which specifies
three standard floating-point arithmetic formats. Two of them are
32-bit and 64-bit formats (with 24-bit and 53-bit precision,
respectively); modern C/C++ compilers almost universally equate these
to float and double. The third is an 80-bit (64-bit precision) format
used for intermediate results in multi-step calculations.

The Intel X86 processors have can perform arithmetic in all three
modes, although it always works internally in 80-bit mode and
inserts automatic conversions for the other two. I don't know
anything about PPCs or Alphas, but the IEC standard is pretty much
universal now, and I'd be mildly amazed if either of them differed
in any important ways.

Exactly how floating-point arithmetic is done is a function of the
compiler, not the operating system. You didn't say which compiler you
were using on Windows, but Microsoft Visual C++ is the most likely.
Both MSVC and EGCS perform intermediate calculations in 80-bit internal
registers wherever possible, but allow values to spill into 64-bit
memory when the compiler can't manage to fit the entire calculation
into registers (a common problem on the register-poor X86
architecture). (The details of exactly how EGCS should handle this
were the subject of heated debate on this list not so long ago.)

It looks like what happened was that, at some critical point in your
program, MSVC allowed a value to spill to 64 bits (thus truncating it
to 53-bit precision) while EGCS was able to keep it in an 80-bit
register (retaining 64-bit precision). (Incidentally, because people
tend to attach far too much importance to this sort of observation, I
hasten to add that this implies nothing about the relative performance
of the two compilers in general; perhaps they were using different
optimisation settings, or perhaps they simple made different decisions
about which intermediate results should be kept in registers and which
sacrificed.)

Both compilers have options to force pure 64-bit arithmetic (53-bit
precision) throughout (at some cost in speed): -ffloat-store on EGCS,
/Op on MSVC.

--
Ross Smith ................................... mailto:ross.s@ihug.co.nz
.............. The Internet Group, Auckland, New Zealand ..............
         "The award for the Most Effective Promotion of Linux
         goes to Microsoft."             -- Nicholas Petreley


WARNING: multiple messages have this Message-ID
From: "Ross Smith" <ross.s@ihug.co.nz>
To: <egcs@egcs.cygnus.com>
Subject: Re: Rounding errors using doubles?
Date: Wed, 31 Mar 1999 23:46:00 -0000	[thread overview]
Message-ID: <002d01be71aa$30d420e0$a8a11dcb@animal.ihug.co.nz> (raw)
Message-ID: <19990331234600.Lxj7bpHGZQBWty_gwq1H2WIJTE2qWoSTvbmzNZq4X-Y@z> (raw)

From: Sam Lantinga <slouken@devolution.com>
>
>I have to thank everyone here on this list for your responsiveness.
>The problem was caused by unexpected values in code using doubles
>that was ported from Windows.  Apparently, by default, Windows uses 
>53 bits of precision for it's double operations.  Linux uses 64 bits.
>
>Since the code relies on the exact behavior of doubles quite extensively,
>we are setting the precision of the FPU to 53 bits using the fldcw
>instruction. :)
>
>BTW, does anyone know what precision is used on the PPC and Alpha
>architectures?

It's not really a difference between operating systems or (to a first
approximation) CPUs.

There's a standard called IEC 559 (formerly IEEE 754), which specifies
three standard floating-point arithmetic formats. Two of them are
32-bit and 64-bit formats (with 24-bit and 53-bit precision,
respectively); modern C/C++ compilers almost universally equate these
to float and double. The third is an 80-bit (64-bit precision) format
used for intermediate results in multi-step calculations.

The Intel X86 processors have can perform arithmetic in all three
modes, although it always works internally in 80-bit mode and
inserts automatic conversions for the other two. I don't know
anything about PPCs or Alphas, but the IEC standard is pretty much
universal now, and I'd be mildly amazed if either of them differed
in any important ways.

Exactly how floating-point arithmetic is done is a function of the
compiler, not the operating system. You didn't say which compiler you
were using on Windows, but Microsoft Visual C++ is the most likely.
Both MSVC and EGCS perform intermediate calculations in 80-bit internal
registers wherever possible, but allow values to spill into 64-bit
memory when the compiler can't manage to fit the entire calculation
into registers (a common problem on the register-poor X86
architecture). (The details of exactly how EGCS should handle this
were the subject of heated debate on this list not so long ago.)

It looks like what happened was that, at some critical point in your
program, MSVC allowed a value to spill to 64 bits (thus truncating it
to 53-bit precision) while EGCS was able to keep it in an 80-bit
register (retaining 64-bit precision). (Incidentally, because people
tend to attach far too much importance to this sort of observation, I
hasten to add that this implies nothing about the relative performance
of the two compilers in general; perhaps they were using different
optimisation settings, or perhaps they simple made different decisions
about which intermediate results should be kept in registers and which
sacrificed.)

Both compilers have options to force pure 64-bit arithmetic (53-bit
precision) throughout (at some cost in speed): -ffloat-store on EGCS,
/Op on MSVC.

--
Ross Smith ................................... mailto:ross.s@ihug.co.nz
.............. The Internet Group, Auckland, New Zealand ..............
         "The award for the Most Effective Promotion of Linux
         goes to Microsoft."             -- Nicholas Petreley



             reply	other threads:[~1999-03-18 17:43 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-03-18 17:43 Ross Smith [this message]
     [not found] ` < 002d01be71aa$30d420e0$a8a11dcb@animal.ihug.co.nz >
1999-03-19  6:36   ` craig
     [not found]     ` < 19990319142042.16973.qmail@deer >
1999-03-19  6:36       ` craig
1999-03-31 23:46         ` craig
1999-03-31 23:46     ` craig
1999-03-31 23:46 ` Ross Smith
  -- strict thread matches above, loose matches on Subject: below --
1999-03-19  9:08 Sam Lantinga
     [not found] ` < E10O2lP-0006t2-00@roboto.devolution.com >
1999-03-19  9:43   ` craig
1999-03-31 23:46     ` craig
1999-03-31 23:46 ` Sam Lantinga
1999-03-18 16:45 Sam Lantinga
1999-03-18 16:54 ` Dima Volodin
1999-03-31 23:46   ` Dima Volodin
     [not found] ` < E10NnPU-0006Cc-00@roboto.devolution.com >
1999-03-18 16:57   ` David Edelsohn
1999-03-31 23:46     ` David Edelsohn
1999-03-31 23:46 ` Sam Lantinga
1999-03-18 15:41 Sam Lantinga
1999-03-18 15:54 ` Dima Volodin
1999-03-31 23:46   ` Dima Volodin
     [not found] ` < E10NmPs-0005mx-00@roboto.devolution.com >
1999-03-18 15:51   ` Sylvain Pion
1999-03-31 23:46     ` Sylvain Pion
1999-03-18 16:12   ` Joe Buck
     [not found]     ` < 199903190011.QAA11085@atrus.synopsys.com >
1999-03-18 16:25       ` Joe Buck
1999-03-31 23:46         ` Joe Buck
1999-03-31 23:46     ` Joe Buck
1999-03-31 23:46 ` Sam Lantinga

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='002d01be71aa$30d420e0$a8a11dcb@animal.ihug.co.nz' \
    --to=ross.s@ihug.co.nz \
    --cc=egcs@egcs.cygnus.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).