Re: Division in C++

"Michael Tiomkin" <tmk@netvision.net.il>
12 Jul 2005 05:14:04 -0400

          From comp.compilers

Related articles
Division in C++ garms@gmx.de (Onno Garms) (2005-07-11)
Re: Division in C++ antounk@comcast.net (Antoun Kanawati) (2005-07-12)
Re: Division in C++ qrczak@knm.org.pl (Marcin 'Qrczak' Kowalczyk) (2005-07-12)
Re: Division in C++ tmk@netvision.net.il (Michael Tiomkin) (2005-07-12)
Re: Division in C++ henry@spsystems.net (2005-07-12)
Re: Division in C++ fw@deneb.enyo.de (Florian Weimer) (2005-07-12)
Re: Division in C++ gdr@integrable-solutions.net (Gabriel Dos Reis) (2005-07-12)
Re: Division in C++ qrczak@knm.org.pl (Marcin 'Qrczak' Kowalczyk) (2005-07-12)
Re: Division in C++ garms@gmx.de (Onno Garms) (2005-07-17)
Re: Division in C++ poenitz@htwm.de (Andre Poenitz) (2005-08-10)
| List of all articles for this month |

From: "Michael Tiomkin" <tmk@netvision.net.il>
Newsgroups: comp.compilers,gnu.g++.help
Date: 12 Jul 2005 05:14:04 -0400
Organization: http://groups.google.com
References: 05-07-046
Keywords: C++, arithmetic
Posted-Date: 12 Jul 2005 05:14:04 EDT

Onno Garms wrote:
> Hello,
>
> I have a short sample program that hangs on one of my
> computer when I compile in debug mode. The program works
> fine on my other computers or if I compile optimized.
>
> The problematic computer and compiler are quite old (gcc2.95
> on a Pentium PC running Linux), but I wonder if the problem
> will occur with other compilers on other computers if I
> change the numbers.
>
> Here is the code:
>
> int main ()
> {
> double a = 96.03755458500125997;
> double b = 3.0;
> double c;
>
> while (1)
> {
> c = a/b;
> if (a/b<=c) break;
> }


    return -5; // the function shoul return a value


> }
>
> Can anybody explain why this hangs?


    There is an old rule: never assume or check equality of two floating
point numbers.


    If you use an x86 processor, its fp regs are 80 bit long. An
expression 'a/b' isn't stored in memory, therefore the compiler can use
its 80-bit value for comparison. The 'c=a/b' expression is stored in a
'double' variable 'c', and it's rounded to a 64-bit fp number.
    It seems that the 80-bit '96.03.../3' is larger than its rounding to
64-bit, which is reasonable - for rounding towards 0 and towards
-infinity the probability of a positive 80-bit number with random
mantissa to be greater than its 64-bit rounding is 0.5.


    For the optimized version of your code, the compiler assigned all
your variables to registers, and then no rounding was performed at all.
This is the reason that you got the same result of computing 'a/b'
twice. The second reason might be that after CSE and dead code
elimination, the body of your loop will be equivalent to the 'break'
statement, and the loop will be removed.


    What is interesting in your case is that the C standard defines the
type of 'a/b' as 'double', and therefore the same rounding should be
performed on the result. Unfortunately, these conversions are very
expensive, and I think that very few compilers perform them as a
default. On many compilers there is an option of being IEEE compatible,
or strictly standard compliant, and then you'd have the same behaviour
you had with "optimized" version of your code.


    Michael


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.