Hey guys,
I have found a paper which seems to be very interesting, let me know if it works, I've tried in python but it doesn't work very well. I'll attach the file to this post. Let me know if ti works in Arduino. Thank you
gamberoillecito:
Ok, thank you for the info, I don't know if it's going to be too slow for my project so far, I'll be able to tell you in few weeks hopefully, but I'm sure that the fastest version will be good. If you send it to me I'll test it and let you kown if it's ok and if it needs any improvements (I don't think so actually)
OK, so here ia some code to calculate hex digits of pi.
[
// Bailey-Borwein-Plouffe PI algorithm by 'jurs' for Arduino forum:
#define cput(x) Serial.write(x);
#define STARTBEHIND 3840
#define NUMDIGITS 192
#define unsigned uint16_t
// for max correct range try 4096 and 6
void setup()
{
Serial.begin(9600);
uint32_t time=millis();
Serial.print("\nStart calculating ");Serial.print(NUMDIGITS);
Serial.println(" hex digits of PI");
Serial.print("first digit is digit #:");
Serial.println(STARTBEHIND+1);
Serial.print("last digit is digit #:");
Serial.println(STARTBEHIND+NUMDIGITS);
Serial.println("\ncalculating...");
hexDigits();
Serial.println("FINISHED");
Serial.print("Calculation time in seconds:\t");
Serial.println((millis()-time)/1000.0);
}
void loop() {
// put your main code here, to run repeatedly:
}
static uint8_t hexdigit (uint8_t n)
{
n += '0';
return n > '9' ? n + 'A'-'0'-10 : n;
}
static unsigned mod_mul (unsigned a, unsigned b, unsigned n)
{
unsigned ab = 0;
while (1)
{
if (a % 2 == 1)
{
ab += b;
if (ab >= n)
ab -= n;
}
a = a / 2;
if (a == 0)
return ab;
b = b * 2;
if (b >= n)
b -= n;
}
}
// Return 16^k mod n
//
// Exponentiation with the same approach as above except
// that we binary-expand the exponent instead of a factor.
static unsigned mod_pow16 (unsigned k, unsigned n)
{
unsigned p = 1;
unsigned _16 = 16;
if (n == 1)
return 0;
while (_16 >= n)
_16 -= n;
while (1)
{
if (k % 2 == 1)
p = mod_mul (_16, p, n);
k = k / 2;
if (k == 0)
break;
_16 = mod_mul (_16, _16, n);
}
return p;
}
// Helper for the function below.
static float tame (float s)
{
int8_t si = (int8_t) lrintf (s);
if (si <= -2 || si >= 2)
s -= si;
return s;
}
// The finite part mod 1 of sigma_j, i.e. partial sum where the exponent
// of 16 is >= 0. By "mod 1" we always mean "up to some integer",
// i.e. the result needs not to be normalized to [0,1).
static float sigma_a (unsigned n, uint8_t j)
{
float s = 0.0f;
for (unsigned k = n-1; k+1 != 0; k--)
{
unsigned j_8k = j + 8*k;
s += mod_pow16 (n-k, j_8k) / (float) j_8k;
// Cut down the sum and don't let it grow too big.
// The bigger the number grows the less precision is
// left for the fractional part we are interested in.
s = tame (s);
}
return s;
}
#define MARGIN 10
static float sigma_b (unsigned n, uint8_t j)
{
float s = 0;
float _16 = 1.0f;
for (unsigned k = n; k <= n + MARGIN; k++)
{
s += _16 / (8*k + j);
_16 /= 16;
}
return s;
}
// Compute an approximation of 16^n * sigma(j) mod 1
// where
//
// sigma_j = \sum_0^oo 1 / (16^k * (8k + j))
//
// The sum is split into two parts:
// sigma_a is the finite sum up to n.
// sigma_b is the finite sum from n+1 to oo
// and approximated by a sum from n+1 to n+MARGIN
float sigma (unsigned n, uint8_t j)
{
return sigma_a (n, j) + sigma_b (n, j);
}
// Compute pi * 16^n up to some integer
// using a Bailey-Borwein-Plouffe formula for pi:
//
// pi = 4*sigma_1 - 2*sigma_4 - sigma_5 - sigma_6
//
// with the definition of sigma_j from above. All this
// is explained very nicely in the French wikipedia at
// http://fr.wikipedia.org/wiki/Formule_BBP
//
// For a proof define the power series
//
// sigma_j (x) = \sum x^{8k} / (8k + j)
//
// write the sum as integral and evaluate it at
// x = sqrt(1/2), see http://www.pi314.net/eng/plouffe.php
float pi_n (unsigned n)
{
float s = 0.0;
for (uint8_t i = 0; i < 4; i++)
{
// j[i] = 1, 4, 5, 6
uint8_t j = i ? i + 3 : 1;
// c[i] = 4, -2, -1, -1
int8_t c = -1;
if (i == 0) c = 4;
if (i == 1) c = -2;
s += c * sigma (n, j);
}
return s;
}
// We computed pi_n = 16^n * pi mod 1
// Get the first fractional hexadecimal digit by multiplying
// with 16 and extracting digit 0 of the result. Voila!
static uint8_t pi_dig16 (unsigned n)
{
return 15 & lrintf (floorf (16 * pi_n (n)));
}
void hexDigits()
{
// As explained above, 16-bit integers limitate us to moduli <= 2^15.
// The biggest modulus for n is 8n+6 so that for n >= 4096 we expect
// garbage from the implementation if 16-bit integers are used like
// with avr-gcc. In fact, we get garbage for n > 4100.
// It's not exacly 4095 because of the denominators in sigma_a that
// delay the garbage for some values of n.
// Easy going 4000 hex-digits of pi.
for (unsigned n =STARTBEHIND; n <STARTBEHIND+NUMDIGITS; n++)
{
// Print a line break after every 64 digits. That way the output
// can easily be compared with, e.g. the hexadecimal representation
// of pi from blowfish listed in "First 8366 Hex Digits of PI" from
// http://www.herongyang.com/Cryptography/
if (n % 64 == 0)
cput ('\n');
// Get the n+1-th hexadecimal digit of pi and
// output it as ASCII character.
cput (hexdigit (pi_dig16 (n)));
}
cput ('\n');
}/code]
Please be aware: Calculation will start behind defined STARTBEHIND digit
So if you want to calculate the first 4100 digits, set defines like that:
#define STARTBEHIND 0
#define NUMDIGITS 4100
Southpark:
But even if somebody can calculate pi to 2^9999999999999999999999999999999999999999999
decimal places...... we'll never get to the 'end'.... because pi just keeps going ..... forever, right?
Depends on your definition of "going". For example, 1.00... goes on forever. It just does so predictably.
Suddenly finding a whole bunch of repeating digits wouldn't help either, as you couldn't know how many follow it without some kind of proof.
aarg:
Depends on your definition of "going". For example, 1.00... goes on forever. It just does so predictably.
Not my definition. For 'pi'...... "going" refers to never getting any infinite number of replicating patterns beyond some stage........ like 1.1442223456782345678234567823456782345678......
For your case....... you're getting replicating patterns immediately, namely replications of '0'... forever.