Recent

Author Topic: Spurious real numbers  (Read 3594 times)

Relativity

  • Full Member
  • ***
  • Posts: 103
Spurious real numbers
« on: October 16, 2015, 09:23:04 am »
My program must calculate the average of two real numbers having each one digit after the comma (no more).
The result is always a number having at most 2 digits after the comma.
In principle I should get results like:

a := 123,1
b := 234,2
c := (a + b)/2 = 178,65

But often, instead of c=178,65 I get c=178,64999999999999 or c=178,65000000000001.

Sometimes I have to check whether 2 of the average numbers calculated this way are equal and I get of course that 178,64999999999999 is not equal to 178,65000000000001, although actually the difference is only due to this error and the numbers should be recognized as equal.
Is there any way to get clean results from simple operations like the one above ?
"How'm I gonna get through?"
  -- Pet Shop Boys

eny

  • Hero Member
  • *****
  • Posts: 1634
Re: Spurious real numbers
« Reply #1 on: October 16, 2015, 10:06:34 am »
There is no absolute precision in real numbers.
Use rounded values or consider them equal if the difference is within a certain bandwidth.

Have a look here: https://www.youtube.com/watch?v=PZRI1IfStY0
« Last Edit: October 16, 2015, 10:09:31 am by eny »
All posts based on: Win10 (Win64); Lazarus 2.0.10 'stable' (x64) unless specified otherwise...

balazsszekely

  • Guest
Re: Spurious real numbers
« Reply #2 on: October 16, 2015, 10:17:41 am »
There is a RoundTo function in the math unit.

Relativity

  • Full Member
  • ***
  • Posts: 103
Re: Spurious real numbers
« Reply #3 on: October 16, 2015, 10:35:48 am »
Thanks a lot to eny and GetMem.
I used the RoundTo function and everything works fine now.
"How'm I gonna get through?"
  -- Pet Shop Boys

Relativity

  • Full Member
  • ***
  • Posts: 103
Re: Spurious real numbers
« Reply #4 on: October 21, 2015, 09:03:31 am »
After some experimenting, I've come now to the conclusion that RoundTo is not the solution to the problem.
RoundTo is a function that rounds a real number to a given number of digits after the comma, so that, in principle, for example:

a := 2,3658;
b := RoundTo(a,-2);

-> b = 2,37

but the result number can still be affected by the said small error, so that you get something like, say:

-> b = 2,37000000000002

As I manage numbers with at most 2 digits after the comma, I find the best solution to make comparisons is something like:

if (Round(100*a) >= Round(100*b)) then
.....

I hope my experience can be useful to somebody in the future.

"How'm I gonna get through?"
  -- Pet Shop Boys

BobS

  • Full Member
  • ***
  • Posts: 153
Re: Spurious real numbers
« Reply #5 on: October 21, 2015, 10:05:08 pm »
Have you tried the Currency type?   It uses integers internally and just scales the number so it looks like a real which should reduce rounding problems.

Edit: it works fine for you example, however it only goes to four decimal places so if you ever need to go beyond that you are back to using the other float types with their impression.
« Last Edit: October 21, 2015, 10:19:31 pm by BobS »

picstart

  • Full Member
  • ***
  • Posts: 236
Re: Spurious real numbers
« Reply #6 on: October 23, 2015, 10:38:36 am »
The representation of real numbers is via notation. We are taught base 10 notation in early childhood an so we see it as the only accurate notation. Our computational buddies namely electrons inside electronic circuits are best suited to binary notation.
Now handheld calculators use binary coded decimal and never leave base 10 notation.
Computers could do this but it is not as fast as pure binary. This means there is a base conversion from base 10 to binary and back. For all values that are a finite power series of 2;  base 10 and base 2 are equivalent.
 0.1 base 10 can't be expressed in base 2 without an infinite power series of 2 so the computer stops at some point ex 64 bits. Accuracy that would be in the 65th bit is missing and when converted back to base 10 produces what coders will call rounding errors. Technically this is not an error it is just the mathematics of number base conversions when using a finite storage unit ( ex 64 bits).

BobS

  • Full Member
  • ***
  • Posts: 153
Re: Spurious real numbers
« Reply #7 on: October 23, 2015, 11:56:35 pm »
Well I remember various ways used by calculators to try to avoid this problem, one was to calculate several digits beyond the precision of the display and apply a rounding algorithm; some were said to keep a copy of a number in memory briefly so if someone did, e.g., the sqrt(2) and immediately squared it the calculator would just pop out the number they started with...caused a lot of "this is cheating" arguments at the time :).

 

TinyPortal © 2005-2018