Hjälp! Hur håller man j**** många decimaler i VB?

Permalänk
Medlem

Hjälp! Hur håller man j**** många decimaler i VB?

Hej! Jag håller på att göra ett program som räknar ut Pi.
Och eftersom 3.14 är trams så bestämde jag mig att få ut så många decimaler jag kan.

Formeln jag använder är

Pi/4 = 4 * tan-1(1 / 5) - tan-1(1 / 239)

Men, detta kommer inte ge mig några decimalers rätt så man måste kalkylera tan-1(1 / 5) samt tan-1(1 / 239) på ett sätt också:

tan-1(z) = z - z^3 / 3 + z^5 / 5 - z^7 / 7 + ...

För att få t.ex 1 miljon decimaler så måste man köra denna funktion 200.000+ gånger.
Men, detta kommer ju ge mig ett jävla antal decimaler. Som jag inte kan hålla med en t.ex Double.
Så jag undrar, hur kan jag göra för att hålla väääääldigt många decimaler?
Har redan googlat som en galning utan resultat..
-ref

Visa signatur

Corsair 750D | i5 4670k | ASUS Z87-a | 8GB Corsair Dominator | Asus GTX770-DC2OC | Samsung 840 EVO 250GB | WD 500GB X2

Permalänk

En snabb googling säger mig att det inte går att ha sådan precision med decimaler i något språk utan att använda något externt Library t.ex Maple(Länk). Min googling kan vara fel, men det kan löna sig att använda dig av t.ex Maple om du vill ha bra precision.

Permalänk
Medlem
Skrivet av Formel117:

En snabb googling säger mig att det inte går att ha sådan precision med decimaler i något språk utan att använda något externt Library t.ex Maple(Länk). Min googling kan vara fel, men det kan löna sig att använda dig av t.ex Maple om du vill ha bra precision.

Känns lite onödigt att köpa massa saker.
Men man kan säkert hitta på något sätt att jobba runt detta?

Visa signatur

Corsair 750D | i5 4670k | ASUS Z87-a | 8GB Corsair Dominator | Asus GTX770-DC2OC | Samsung 840 EVO 250GB | WD 500GB X2

Permalänk

Såg inte att Maple kostade pengar, men det finns förmodligen flera andra alternativ som är gratis och kanske till och med Open Source att hitta på nätet. Sök efter t.ex High Precision Math Library på Google.

Permalänk
Medlem

Denna hittade jag på wikipedia. " 10 trillion (10^13) digits in 2011 by Alexander Yee and Shigeru Kondo" de borde räcka?

Permalänk
Entusiast

Detta är bara en ide, men kan du inte spara decimalerna som en textsträng eller liknande?
Det borde också hjälpa när du lägger till de nya decimalerna i variablen, eftersom du inte ska göra en matematiskt beräkning när du lägger till siffrorna till de befintliga

(Observera att jag kan vara helt ute och cykla nu, klockan är ändå 4 på natten )

Permalänk
Medlem
Skrivet av Ptah:

http://upload.wikimedia.org/math/d/b/e/dbe37f5e3a806ee7d6bf54...

Denna hittade jag på wikipedia. " 10 trillion (10^13) digits in 2011 by Alexander Yee and Shigeru Kondo" de borde räcka?

Den säger ju inte hur jag ska spara uträkningen. Eftersom att K kommer att ändras hela tiden så måste jag ju i det fallet läsa ett tal som blir längre och längre hela tiden och så uppkommer mitt problem hela tiden.

Men det verkar vara en bra formula iaf Tack tack

Visa signatur

Corsair 750D | i5 4670k | ASUS Z87-a | 8GB Corsair Dominator | Asus GTX770-DC2OC | Samsung 840 EVO 250GB | WD 500GB X2

Permalänk
Datavetare

Man måste representera så stora tal på speciella sätt. Men är du bara interesserad av att få ut talet i textform så finns den algorimer som räknar ut Pi decimal för decimal. En sådan beskrivs i denna pdf.

Pdf-dokumentet beskriver algoritmen i språket Haskell, som du kanske inte känner till. För att implementera denna algoritm behöver du kunna representera väldigt stora heltal, d.v.s långt större tal än vad som får plats på 64-bitar. Har inte programmerat VB sedan VB6 och på den tiden hade VB inte stöd för stora heltal. Java och språk som kör på en JVM, t.ex. Cojure och Scala, har alla stöd för detta via Javas Bignum klass.

I C/C++ finns det bibliotek som lägger till stöd för godtyckligt stora heltal, ett sådant är The GNU
Multiple Precision
Arithmetic Library
.

Råkade ha ett C++ program skrivet som gör just det du vill och som använder den "streaming" algoritm som beskrivs i Pdf-dokumentet.

#include <functional> #include <iostream> #include <sstream> #include <gmpxx.h> using namespace std; class Matrix { mpz_class m[4]; public: Matrix(const mpz_class &q, const mpz_class &r, const mpz_class &s, const mpz_class &t) { m[0] = q; m[1] = r; m[2] = s; m[3] = t; } const mpz_class &operator()(int row, int col) const { return m[(row<<1) + col]; } }; Matrix operator*(const Matrix& lhs, const Matrix& rhs) { return Matrix(lhs(0,0) * rhs(0,0) + lhs(0,1) * rhs(1,0), lhs(0,0) * rhs(0,1) + lhs(0,1) * rhs(1,1), lhs(1,0) * rhs(0,0) + lhs(1,1) * rhs(1,0), lhs(1,0) * rhs(0,1) + lhs(1,1) * rhs(1,1)); } Matrix lfts(int k) { return Matrix(k, 4*k+2, 0, 2*k+1); } int extr(const Matrix &z, int x) { mpz_class bn = (z(0,0) * x + z(0,1)) / (z(1,0) * x + z(1,1)); return bn.get_si(); } bool is_safe(const Matrix &z, int n) { return n == extr(z, 4); } int next(const Matrix &z) { return extr(z, 3); } Matrix prod(const Matrix &z, int n) { return Matrix(10, -10 * n, 0, 1) * z; } void pi(function<void(int,int)> digit_fn, int num_digits) { Matrix z(1, 0, 0, 1); int k = 1; int n = 0; while (n < num_digits) { int y = next(z); if (is_safe(z, y)) { digit_fn(y, n); z = prod(z, y); ++n; } else { z = z * lfts(k); ++k; } } } void show_digit(int d, int n) { cout << d; if (n == 0) cout << '.'; cout.flush(); } int main(int argc, char *argv[]) { int N = 10; if (argc > 1) stringstream(argv[1]) >> N; pi(show_digit, N); cout << endl; }

Dold text

Bygg detta program och skicka med en miljon som argument. Borde ta ett par timmar att räkna ut, men du borde få ditt svar

Edit: blev lite copy&paste fel i koden. Fixat nu...

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem
Skrivet av Yoshman:

[codee]Man måste representera så stora tal på speciella sätt. Men är du bara interesserad av att få ut talet i textform så finns den algorimer som räknar ut Pi decimal för decimal. En sådan beskrivs i denna pdf.[/codee]

Pdf-dokumentet beskriver algoritmen i språket Haskell, som du kanske inte känner till. För att implementera denna algoritm behöver du kunna representera väldigt stora heltal, d.v.s långt större tal än vad som får plats på 64-bitar. Har inte programmerat VB sedan VB6 och på den tiden hade VB inte stöd för stora heltal. Java och språk som kör på en JVM, t.ex. Cojure och Scala, har alla stöd för detta via Javas Bignum klass.

I C/C++ finns det bibliotek som lägger till stöd för godtyckligt stora heltal, ett sådant är The GNU
Multiple Precision
Arithmetic Library
.

Råkade ha ett C++ program skrivet som gör just det du vill och som använder den "streaming" algoritm som beskrivs i Pdf-dokumentet.

#include <functional> #include <iostream> #include <sstream> #include <gmpxx.h> using namespace std; class Matrix { mpz_class m[4]; public: Matrix(const mpz_class &q, const mpz_class &r, const mpz_class &s, const mpz_class &t) { m[0] = q; m[1] = r; m[2] = s; m[3] = t; } const mpz_class &operator()(int row, int col) const { return m[(row<<1) + col]; } }; Matrix operator*(const Matrix& lhs, const Matrix& rhs) { return Matrix(lhs(0,0) * rhs(0,0) + lhs(0,1) * rhs(1,0), lhs(0,0) * rhs(0,1) + lhs(0,1) * rhs(1,1), lhs(1,0) * rhs(0,0) + lhs(1,1) * rhs(1,0), lhs(1,0) * rhs(0,1) + lhs(1,1) * rhs(1,1)); } Matrix lfts(int k) { return Matrix(k, 4*k+2, 0, 2*k+1); } int extr(const Matrix &z, int x) { mpz_class bn = (z(0,0) * x + z(0,1)) / (z(1,0) * x + z(1,1)); return bn.get_si(); } bool is_safe(const Matrix &z, int n) { return n == extr(z, 4); } int next(const Matrix &z) { return extr(z, 3); } Matrix prod(const Matrix &z, int n) { return Matrix(10, -10 * n, 0, 1) * z; } void pi(function<void(int,int)> digit_fn, int num_digits) { Matrix z(1, 0, 0, 1); int k = 1; int n = 0; while (n < num_digits) { int y = next(z); if (is_safe(z, y)) { digit_fn(y, n); z = prod(z, y); ++n; } else { z = z * lfts(k); ++k; } } } void show_digit(int d, int n) { cout << d; if (n == 0) cout << '.'; cout.flush(); } int main(int argc, char *argv[]) { int N = 10; if (argc > 1) stringstream(argv[1]) >> N; pi(show_digit, N); cout << endl; }

Dold text

Bygg detta program och skicka med en miljon som argument. Borde ta ett par timmar att räkna ut, men du borde få ditt svar

Edit: blev lite copy&paste fel i koden. Fixat nu...

Dold text

Good read, tack för hjälpen. Hittade en class som skulle kunna hålla stora nummer, ska lalla runt lite med den först sen ska jag försöka mig på detta.

Visa signatur

Corsair 750D | i5 4670k | ASUS Z87-a | 8GB Corsair Dominator | Asus GTX770-DC2OC | Samsung 840 EVO 250GB | WD 500GB X2

Permalänk

Visual Basic är det värsta språk du kan jobba med eftersom det är så enkelt men ändå så svårt

Visa signatur

CPU: i7 3930k Moderkort: Rampage IV Extreme Kylare: Corsair H100i RAM: 64 GB Corsair Dominator Platinum 1600mhz Grafikkort: EVGA GTX 780 SC (SLI planerat) SSD: Samsung 840 Pro 256 gb Övrig lagring: WD black 2 TB x 2 Chassi: 900D PSU: Corsair 1200i Skärmar: 2x GW2750HM 1x GL2750HM