Page 1 of 1

Precision (C++)

Posted: Thu Mar 27, 2008 1:11 am
by Zacariaz
Well, as you might have guessed, it's all about precision.
I want to do a very simple calculation, but with maximum precision.
What I am talking about is what I think called... well I really have no idea what it's called in english, but it doesn't matter, heres an example:

(1- 1/2)(1 - 1/3)(1 - 1/5)(1 - 1/7)...
or
(1 - 1/p1)(1 - 1/p2)(1 - 1/p3)(1 - 1/p4)...

As you see primes is the key element here, but that is not my problem, i've allready written a fairly inginious prime class ;)

The problem, of course, is that if i do the above calculation straight forward, I will soon run in to some serious precision issues, so instead i want to do it like this:

Code: Select all

p1-1   p2-1   p3-1   p4-1
---- * ---- * ---- * ---- ...
 p1     p2     p3     p4
The first obious advantage is that i can multiply the nominators and denominators thus ending up with a single division, but allso another trick is left:

Code: Select all

1   2   4   6
- * - * - * - ...
2   3   5   7
This can easily be converted in such a way that... well i can't explain it, sorry for my poor english.

Code: Select all

 1    2/2   4   6/3
--- * --- * - * --- ...
2/2   3/3   5    7
equaling:

Code: Select all

1   1   4   2
- * - * - * - ...
1   1   5   7
thus our final nominator and denominator will be as small as possible but still yelding the same result.

I have tryed to figure out a smart way to im pliment all this, but I'm simply not experienced enough, so I was hoping that someone would give it a try.

Nb.
This is not something important, the result isn't very important and the reason I started this little experiment was really only for the sake of the experiment, so if nobody other than me finds it of interested, then be it.

Thanks anyway for reading ;)

Posted: Thu Mar 27, 2008 1:25 am
by JamesM
Uuuuhh, sorry, but:

Code: Select all

1       1
-  != ----
2      2/2
2/2 = 1, not 2!

Also, your starting and ending expressions are *completely different*! Just get out your calculator and check! You've managed to do:

Code: Select all

1/2 * 1/3 = 1
Which, I grant you is pretty impressive, but wholly wrong! ;)

Posted: Thu Mar 27, 2008 1:52 am
by Zacariaz
JamesM wrote:Uuuuhh, sorry, but:

Code: Select all

1       1
-  != ----
2      2/2
2/2 = 1, not 2!
but i didn't say that.
JamesM wrote: Also, your starting and ending expressions are *completely different*! Just get out your calculator and check! You've managed to do:

Code: Select all

1/2 * 1/3 = 1
Which, I grant you is pretty impressive, but wholly wrong! ;)
ok, here goes....
( 1 * 2 * 4 * 6 ) / ( 2 * 3 * 5 * 7 )
==
48 / 210
==
0,22857142857142857142857142857143
==
( 1 * ( 2 / 2 ) * 4 * ( 6 / 3 ) ) / ( ( 2 / 2 ) * ( 3 / 3 ) * 5 * 7 )
==
8 / 35
==
0,22857142857142857142857142857143
i did do the math, just to be on the safe side.

Posted: Thu Mar 27, 2008 7:44 am
by bewing
There is an entire class of mathematics software called "arbitrary precision arithmetic." In order to do this sort of calculation, you need such a package. If you just google around a bit with that search term (or go to wikipedia) I think you will find many freeware open-source packages.

Posted: Thu Mar 27, 2008 8:01 am
by Combuster
why not simply write

Code: Select all

0
:twisted:

Posted: Thu Mar 27, 2008 10:19 am
by Zacariaz
bewing wrote:There is an entire class of mathematics software called "arbitrary precision arithmetic." In order to do this sort of calculation, you need such a package. If you just google around a bit with that search term (or go to wikipedia) I think you will find many freeware open-source packages.
But then i wouldn't learn anything...

anyway, i'll take yet another wach at it when i get the time.

Posted: Thu Mar 27, 2008 1:48 pm
by bewing
If you want to learn, then the wikipedia article will give you hints on how to write your own.
Or, you can always take apart other people's code, to learn.

Basically, you need to understand how floating point arithmetic is done in a machine. There is an IEEE standard for it. What the software does is extend the "exponent" and the "mantissa" to be infinitely long, by allocating new dwords/qwords to handle the extra bits when they overflow.
And then the standard package of arithmetic functions are modified to use arbitrary length exponents and mantissas.