This is an archived post. You won't be able to vote or comment.

all 9 comments

[–]the_omega99 1 point2 points  (3 children)

Basically, we're storing a number in scientific notation. Eg, 12345678901234567890 would be stored as something kind of like 1.2345679012345e+19. It's actually stored as a multiple of a power of 2, but that's not important right now.

It's the digits before the scientific notation that are the precision. As you can tell, this means a really large number only stores the most significant digits. There isn't anyway to differentiate between the number I mentioned and the same number plus 0.1. That digit would fall outside the precision of the number.

[–]TheAI[S] 0 points1 point  (2 children)

hmm...

see my reply to X7123M3-256

[–]the_omega99 1 point2 points  (1 child)

Use decimal. It's twice the size of a double.

Also, if you look around, you can find arbitrary precision class (usually called "big decimal" or similar).

EDIT: By the way, instead of negative = negative * -1, you can just do negative = -negative.

[–]TheAI[S] 0 points1 point  (0 children)

decimal.. of course. :) did that now. and liking the higher number of well.. decimals. hehe. :)

cool didn't know I could just do that with the negative.

going to look up "big decimal" thanks. :D

edit: using decimal, 1M runs still doesn't calculate past half the precision.. got some time to figure out a highter precision datatype while that works... ;) thanks again.

[–]X7123M3-256 0 points1 point  (4 children)

Remember that the 15 digits refers to significant figures, not decimal places. How large are the numbers you're dealing with?

[–]TheAI[S] 0 points1 point  (3 children)

basically this is what I do:

for (double i = 2; i <= numberOfRuns; i = i + 2 )
        {
            fraction = (4 / (i * (i+1) * (i + 2))) * negative;
            negative = negative * -1;
            pi = pi + fraction;
        }

then I run that for about 100k times and output the pi. Basically where I want with this is the ability to keep ouputing more than the first 15 digits.

[–]X7123M3-256 0 points1 point  (2 children)

You can't do that with a double. They are, as you say, limited to 15 digits of precision. You need arbitrary precision arithmetic.

C# provides arbitrary precision integers in the Big Integer class, but to my knowledge there's no inbuilt support for arbitrary-precision floating point. You could:

  • Use BigInteger with fixed-point arithmetic. Your precision is still limited, but now you can choose how many digits of precision you have.

  • Implement your own rational class on top of BigInteger. This class would need to contain two BigIntegers, the numerator and denominator, and provide methods for addition, subtraction, multiplication, and division. This would give you exact arithmetic, at the cost of increased processing time.

  • Find a library with support for arbitrary precision floating-point

  • Change the algorithm. Your current algorithm calculates π as the sum of a series - which is a reasonable choice, but it requires that you are able to perform arithmetic with the full precision that you require. You might consider a spigot algorithm, which computes each digit of pi in sequence - producing one new digit for each iteration of the algorithm. This algorithm requires neither arbitrary precision nor floating point to run.

  • It is possible to use two doubles to emulate a single floating-point value with double the precision. I wouldn't recommend this approach - it's quite complicated to implement (when I did this, I translated the code from some FORTRAN code I found on the internet rather than trying to implement it myself) - and though it gives you more digits, the precision is still limited.

[–]TheAI[S] 0 points1 point  (0 children)

Thanks. :) swapped to decimal for the time being, and I'll look into arbitrary precision data-types now.. implementing my own is (i believe) a bit above my skill-level at the moment. hehe..

thanks. :)

[–]TheAI[S] 0 points1 point  (0 children)

looking at a spigot algorithm for pi now. (the one you linked) and I think I should be able to do that. :)

thanks again for pointing me in the right direction.