Προς το περιεχόμενο

Υπολογισμός του e σε ΠΟΛΛΆ δεκαδικά.


SpyrosR

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλησπέρα. :-)

 

Τελευταία έχω αρχίσει να ψάχνομαι με C#... και είπα να φτιάξω κάτι μικρό "για να μάθω".

 

Το πρόγραμμα θέλω να υπολογίζει τον αριθμό e, με ακρίβει πολλών ψηφίων (και εννοώ εκατομμυρίων). Βρήκα στο διαδίκτυο πως ο τύπος υπολογισμού του e είναι "1/0! + 1/1! + ... + 1/n!". Το πρόβλημα μου είναι υλοποίησης βασικά, όχι συνακτικό. Δεν έχω ξανασχοληθεί με τόσο μεγάλα νούμερα και κολλάω κάπως...

 

Με double δε μπορώ να βγάλω παραγοντικό άνω του 65, και προφανώς δε μπορώ και να υπολογίσω πέραν των 16 ψηφίων. Πως πάμε πιο πέρα; Μεταβλητή με μεγαλύτερο εύρος δεν υπάρχει.

 

Μία σκέψη μου ήταν να χρησιμοποιήσω strings... δηλαδή να προσθέτω στο τέλος του string το νούμερο που βρήκα στην προηγούμενη επανάληψη του loop υπολογισμού του e... καλό σαν ιδέα, αλλά: το ίδιο πρέπει να γίνει και για τα παραγοντικά. Εδώ κολλάω, μιας και με τα παραγοντικά διαιρώ... και δε γίνεται να τα έχω σε string. Το τελικό αποτέλεσμα δε πειράζει, καθώς δε κάνω άλλη πράξη με αυτό. Αλλά για τα παραγοντικά τι κάνω;

 

:fear:

 

Ίσως τα είπα κάπως μπερδεμένα, οπότε παραθέτω και τον κώδικα μήπως βοηθάει. Αλλά δε το νομίζω. Έχει ο Θεός. :P

 

 

>using System;

public class EulerCalc
{
   static double Factorial(double Number)
   {
       if(Number <= 1)
       {
           return 1;
       }
       else
       {
           return (Number * Factorial(Number - 1));
       }
   }
   static double Euler(double Number)
   {
       if (Number == 0)
       {
           return 1;
       }
       else
       {
           return (1.0 / Factorial(Number)) + Euler(Number - 1);
       }
   }
   static void Main()
   {
       Console.WriteLine(Euler(65));
       Console.ReadLine();
   }
}

 

Δημοσ.

Φυσικά θες πράξεις άρα δεν σου κάνει ένα string.

 

Καταρχήν η C# δεν είναι για τέτοια πράγματα.

Η C/C++ ή Fortran θα χρησιμοποιήσεις και πάλι θές μεγάααααλο υπολογιστή.

Βέβαια και με basic γίνεται αλλά...

 

Το να ξεκινήσεις να ανακαλύψεις το dna με έναν παιδικό μεγεθυντικό φακό είναι λίγο δύσκολο! Θέλεις πράξεις με μεγάλους αριθμούς (σε Bytes μεγαλους).

Στο διαδίκτυο θα βρέις πάντως αντικείμενα για μεγάλους πραγματικούς αριθμούς σε C/C++.

 

 

Δες εδώ απο ένα παρόμοιο θέμα που είχα παλιότερα:

 

Για "μεγάλους" σε byte αριθμούς, ορίζεις ένα struct ή class που να έχει bytes εσωτερικά και κάνεις overload ότι πράξεις θέλεις. Ο τρόπος-αλγόριθμος που γίνονται οι πράξεις, είναι γνωστός απο το δημοτικό. Μην παραξενευτείς, αλλά με τον ίδιο τρόπο μπορούν να εφαρμοστούν στους υπολογιστές. Π.χ πολλαπλασιασμός.

 

και ένα παράδειγμα για το ξεκίνημα της υλοποίησης:

>
// xxx.cpp : Defines the entry point for the console application.
//

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "stdafx.h"

class MyInt128 {
unsigned char x[16];
void inc(size_t position, signed char increment){
	//αυξησε ή μειωσε κατά 1 την τιμή της *this ξεκινώντας απο την θέση position
	assert(increment==1 || increment==-1);
	if(increment>0){
		if(position < sizeof(x)/sizeof(x[0])){
			if( ++x[position] == 0)
				//έγινε overflow, μετέφερε το κρατουμενο 
				//στο επόμενο byte
				inc(position+1,increment);
		} else 
			status.overflow = 1;
	} else if (increment<0){
		if(position < sizeof(x)/sizeof(x[0])){
			if( --x[position] == (unsigned char)~0u)
				//έγινε underflow, μετέφερε το κρατουμενο 
				//στο επόμενο byte
				inc(position+1,increment);
		} else 
			status.underflow = 1;
	}
}
struct _status {
	unsigned char overflow:1;
	unsigned char underflow:1;
	_status() { memset(this,0,sizeof(*this)); }
} status;
public:
MyInt128() { memset(x,0,sizeof(x)); }
MyInt128(const MyInt128&  { memcpy(x,b.x,sizeof(x)); }
//εδώ πρέπει να προσθέσεις ότι άλλους constructor θα σου χρησιμεύσουν...

MyInt128& operator ++(void) { status = MyInt128::_status();  inc(0,1);  return *this; }

MyInt128& operator --(void)  {  status = MyInt128::_status();  inc(0,-1);  return *this; }

int operator == (const MyInt128& a) const 
	{  return (!memcmp(x,a.x,sizeof(x))) ; }

//εδω πρέπει να φτιάξεις operator και για τους άλλους τελεστές που σε ενδιαφέρουν...
};

int main(void){
      MyInt128 a,b;
      ++a;++a;++b;--a;
      printf("a==b? :%s\n",(a== ? "TRUE" : "FALSE");
      --a;
      printf("a==b? :%s\n",(a== ? "TRUE" : "FALSE");
      printf("press any key\n");
      getchar();
      return 1; //βαρέθηκα το 0!
}

Δημοσ.

για κοίτα τη κλάση που έφτιαξε αυτός εδώ:

http://www.carljohansen.co.uk/bigint/

 

ή δεν σε βοηθήσει το παραπάνω με ένα γρήγορο search είδα οτι oi F# και J# έχουν BigInt class. Κάνοντας reference τα αντίστοιχα dll θεωρητικά θα μπορείς να τα χρησιμοποιήσεις.

 

αλλιώς όπως είπε και ο φίλος πιο πάνω περίμενε .net4 :)

Δημοσ.
BigDouble θέλει, όχι BigInt

 

Γινετε και με το bigint, να και η αποδειξη.

( το εγραψα σε ενα αρχειο γιατι ειναι μεγαλος, το μεγεθος του αριθμου ειναι 100kb)

e.zip

Δημοσ.

Google... :)

 

A tiny program to compute e

 

e on your computer. A program of the same kind exists for This is a tiny C program from Xavier Gourdon to compute 9000 decimal digits of p .other constants defined by mean of hypergeometric series and for some

 

>
{;(for(n=N--;--n;a[n]=x%n,x=10*a[n-1]+x/n
((for(;N>9;printf("%d",x
;main(){int N=9009,n=N,a[9009],x;while(--n)a[n]=1+1/n

 

the constant compute more digits (change the value 9009 to more) and to be faster (change This program has 117 characters (try to do better !). It can be changed to 10 to another power of 10 and the printf .command). A not so obvious question is to find the algorithm used

Δημοσ.
Google... :)

 

A tiny program to compute e

 

e on your computer. A program of the same kind exists for This is a tiny C program from Xavier Gourdon to compute 9000 decimal digits of p .other constants defined by mean of hypergeometric series and for some

 

>
{;(for(n=N--;--n;a[n]=x%n,x=10*a[n-1]+x/n
((for(;N>9;printf("%d",x
;main(){int N=9009,n=N,a[9009],x;while(--n)a[n]=1+1/n

 

the constant compute more digits (change the value 9009 to more) and to be faster (change This program has 117 characters (try to do better !). It can be changed to 10 to another power of 10 and the printf .command). A not so obvious question is to find the algorithm used

 

Μαλλον κατι πηγε πολυ στραβα στο copy-paste

 

>
#include <stdio.h>
main(){int N=9009,n=N,a[9009],x;while(--n)a[n]=1+1/n;
for(;N>9;printf("%d",x))
for(n=N--;--n;a[n]=x%n,x=10*a[n-1]+x/n);}

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...