Charles Stack on Sat, 20 Nov 1999 14:25:05 -0500 (EST)


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

RE: [Plug] Strange floating point behavior with C++


Problem you are encountering is that many floating point numbers can not be
accurately represented as a binary number.  For example, 4/100's.  We
interpret it as .04.  But, the computer attempts to represent this base-2.
Hence, the strange results you encounter.  If you had a decimal that was a
power of 2 (i.e 1/2, 1/4,..1/1028), it could be represented in a finite
number of digits.

My suggestion is that you:

1) Extract the integer portion first.
2) Multiply the decimal portion by the maximum precision you desire (say
10^6).
3) Extract and save the integer portion.
4) Now, working backwards, divide the number by 10.  If the remainder is
zero, and the quotient is not, then repeat this step.
5) If the remainder is not zero, then you are finished.
6) Now, determine the number of digits in the result by repeated dividing
the quotient from step 4 and incrementing a count until the quotient equals
zero.

This still won't totally solve your problem.  But, it will prevent the
infinite loop you've encountered.  The only other alternative is to use BCD
numbers or to create your own flowing point type that included a numerator
and denominator.

HTH,

Charles

-----Original Message-----
From: Morgan Wajda-Levie [mailto:mpwl@locke.ccil.org]
Sent: Saturday, November 20, 1999 2:53 PM
To: Plug
Subject: [Plug] Strange floating point behavior with C++


I know that this is not a C programming mailing list, but a lot of
Linux people know C, and this is C code being written on Linux, so
it's somewhat applicable.

I'm writing a function in C++ that takes a floating point number and
returns the number digits of precision it has.  I'm doing this with
the following code:

  int f_digits(float number)
  {
    int a;
    number -= int(number);
    if(!number) return(0);
    for(a = 0; int(number / pow(10, a)) != number / pow(10, a); a--)
      {
      }
    return(a);
  }

As far as I can tell, the code looks like it should work.  If the
number has two digits of precision, it should be evenly divisible by
10^-2, or 10.01.  Instead, it loops infinitely.  By running it through
gdb, I find that it claims that number = 0.400024414, when it should
be .4.  (123.4 - 123).  I tried dividing this number by 10^-9 in the
debugger, and I wrote everything out by hand.  Somehow, it came up
with the following:

.400024414 / .000000001
$4 = 400024413.99999994

Why can't C++ use floating point numbers accurately?

Also, for system info: I'm running Debian potato with glibc 2.1.2-10
and gcc 2.95.2-3.
--
Morgan Wajda-Levie
http://www.worldaxes.com/wajdalev
PGP fingerprint:
A353 C750 660E D8B6 5616  F4D8 7771 DD21 7BF6 221C
http://www.worldaxes.com/wajdalev/public.asc for PGP key
encrypted mail preferred


_______________________________________________
Plug maillist  -  Plug@lists.nothinbut.net
http://lists.nothinbut.net/mail/listinfo/plug