mam przykładową liczbę 125 i chcę aby zmienna a:= przypisała mi 3 czyli ilosc cyrf w tej liczbie. Czy jest jakaś funkcja, która by to zrobila? bardzo prosze o pomoc
można tak :
a := Length(IntToStr(125));
lub
a := Length(FloatToStr(125.23));
a:=1+trunc(ln(liczba)/ln(10));
ile cyfr ma 5 milionów silnia? można to policzyć w około sekundę.
a jezeli wprowadzam N liczbe?
Nati napisał(a)
a jezeli wprowadzam N liczbe?
To co ??? Masz gotowe przykłady, nie łaska samemu sprawdzić, najlepiej od razu na forum :-[
@mgr.dobrowolski napisał
a:=1+trunc(ln(liczba)/ln(10));
ile cyfr ma 5 milionów silnia? można to policzyć w około sekundę
Aby trochę uprościć zapis, użyję funkcji log10 (=log o podstawie 10)
Domyślam się, że log10(5000000!) chcesz liczyć tak log10(1)+log10(2)+...+log10(5000000). Wskutek zaokrągleń może się okazać, że otrzymamy (liczby są trochę z "kapelusza") 31323380.99999999999 zamiast poprawnej wartości 31323381.00000001. Po nałożeniu truncate() mamy 31323380 zamiast 31323381.
bogdans napisał(a)
...może się okazać, że otrzymamy (liczby są trochę z "kapelusza") ...
Masz rację [browar], ale... Policzyłem tą sumę w trzech zmiennych różnych typówsingle 32111682.0000000000 1.0000000000
double 31323381.3607372700 2.2947599831
extended 31323381.3607387790 2.2947679690
Dodałem jeszcze kolumnę 10^frac(sumalog), czyli kilka pierwszych cyfr 5000000!
Licząc z dokładnością 57 cyfr otrzymałem:
31323381.360738778470983953161616130130465078847055
oraz
2.2947679648766241864247490203462335982382063337701
Liczbę cyfr n! lepiej liczyć tak: trunc(1 + (ln(2*pi*n)/2 + n*ln(n) - n) / ln(10)), tu otrzymałem 31323382.
Czyli double okazało się wystarczające.
Ja byłem trochę bardziej ambitny, wpierw wyszukałem w przedziale <1;106> takie liczby n1 oraz n2, że log10(1)+log10(2)+...+log10(n1) oraz log10(1)+log10(2)+...+log10(n2) są najbliższe liczby całkowitej.
n1 = 549545 suma logarytmów przekracza o 1,709910-6 liczbę całkowitą
n2 = 833851 suma logarytmów jest o 2,108510-6 mniejsza od liczby całkowitej
A teraz liczę (w Pythonie) 549545!, po wyliczeniu porównam wyniki.
Niestety komputer zawisł w okolicach 315000!, stosując opisane wyżej kryteria wybrałem liczby n1=108965
oraz n2=258335 z przedziału <1;300000>. Oba sposoby liczenia ilości cyfr (sumowanie logarytmów, obliczenie silni => konwersja na string => funkcja len()) dają ten sam wynik.
Myślę, że od tego jak dokładnie liczymy logarytm (ilu cyfrowa są nasze Tablice Matematyczne) zależy jak wielkie silnie możemy szacować, no to ja to pobadam od tej strony.
var n:dword; lp,sl,p,p1,l10:extended;
begin
p:=1; lp:=0; // p=10^lp
l10:=1/ln(10); //log_10(x) = ln(x)/ln(10)
repeat
n:=1;
p1:=1/p; // jezeli bez bólu da się zastąpić dzielenie mnożeniem to warto
sl:=0; // sum(i=1..n,log10(i))
repeat
n+=1;
sl+=trunc(ln(n)*l10*p)*p1;
until trunc(1 + (ln(2*pi*n)/2 + n*ln(n) - n) / ln(10))<>1+trunc(sl);
writeln(lp:8:0, n:12, ' ',sl);
p*=10; lp+=1;
until n=10;
end.
Trzebaby chyba mieć pecha, żeby nie pokazała się tu któraś z liczb znalezionych przez Ciebie, no i jest (11).
Wyniki obliczeń:■ Free Pascal IDE Version 0.9.2
Using "C:\pp\bin\win32\cygwin1.dll" version 1001.8.0.0
The cygwin1.dll that you have in "C:\pp\bin\win32\cygwin1.dll" is too old
If the IDE does not work correctly, please consider
putting a newer cygwin1.dll version in your path before that one.
Running "c:\download\cyfry.exe "
0 4 0.0000000000000000E+0000
1 5 1.9000000000000000E+0000
2 22 2.0960000000000000E+0001
3 95 1.4797900000000000E+0002
4 197 3.6799040000000000E+0002
5 197 3.6799937000000000E+0002
6 1944 5.5509995140000000E+0003
7 5935 1.9819999753000000E+0004
8 8998 3.1673999981620000E+0004
9 43628 1.8347899999833500E+0005
10 165535 7.9202099999641390E+0005
11 549545 2.9157289999989533E+0006
12 2159448 1.2740850999999445E+0007
13 5814278 3.6805553999999755E+0007
14 9242360 6.0366370999999972E+0007
15 28563732 2.0056083299999999E+0008
16 48655817 3.5289287399999999E+0008
dalej już nic ciekawego
W wierszu sl+= zamieniłem trunc() na round()<code> 0 6 3.0000000000000000E+0000
1 22 2.1000000000000000E+0001
2 95 1.4799000000000000E+0002
3 197 3.6798500000000000E+0002
4 2948 8.9499995000000000E+0003
5 8060 2.7987000030000000E+0004
6 17411 6.6278000079000000E+0004
7 258335 1.2859659999955000E+0006
8 2064173 1.2138273000000490E+0007
(swoją drogą, dziedziny trunc i round są różne?)
W trzeciej kolumnie jest więcej cyfr niż w pierwszej, ale wiadomo, 1/10 jest dwójkowo liczbą okresową.
Pierwsza kolumna mówi o tym ile cyfr po przecinku mają nasze Tablice Logarytmów
Druga, o tym jak wielkie silnie możemy szacować.
Trzecia to suma logarytmów od 1 do n.
Założyłem, że trunc(1 + (ln(2pin)/2 + n*ln(n) - n) / ln(10)) jest równe 1+trunc(log_10(n!)) i chyba jest dla n>1, kiedyś to sprawdzałem, wynika to ze zlogarytmowania (łoj co za słowo) przybliżenia Styrlynga:
Swoją drogą, rzecz która jest może i ciekawsza od , nie koniecznie ładniejsza.
wzorek wziąłem z sieci, ale czegoś mi tu brakuje, czy tylko mi się zdaje?
Tylko Ci się zdaje, dobrze napisałeś wzór Stirlinga.
pozdrawiam
Jeżeli lubisz pobawić się silnią to warto zobaczyć: http://www.luschny.de/math/factorial/index.html
Znalazłem dokładniejszy wzór Stirlinga
jest nieznane, ale pozwala oszacować błąd popełniany w tym wzorze