Rechnen mit sehr großen Zahlen mit AppleScript fehlerhaft (7,01E+8 statt 701 mio)

Ludwig11

Granny Smith
Registriert
31.05.09
Beiträge
16
Hallo,

Habe heute früh angefangen mich in AppleScript einzulesen. Bitte also jetzt schon mal fachlich nicht korrekte Ausdrücke entschuldigen - Danke ;)
(Kann auch sonst keine Programmiersprache... alles hat halt einen Anfang^^;)

Mein erstes Skript berechnet die Fibonacci Zahlen.
(Was ist das? -> eine Zahlenreihe bei der immer die 2 Vorhergehenden Zahlen der Reihe addiert werden. Man startet bei der Zahl 1.
1. Fibonacci Zahl: 1
2.: die Zahl vor 1 ist Null, daher 0 +1 = 1
3.: 1+1 = 2
4.: 1+2= 3
4.: 2+3= 5
5.: 3+5= 8
USW. ... Wikipedia erklärt das sicher besser als ich)

Es gibt genügend Scripts (per Google gefunden) die auf diese primitive Art die Fibonacci Zahlen "abzählen".
Für große Zahlen muss aber immer mehr/länger gerechnet werden und das Script braucht einfach zu lange.
Das ist mir zu öde, nervig und primitiv^^.

Man kann die Zahlenreihe auch berechnen ohne mindestens 2 Zahlenwerte eingeben zu müsse, bzw. für die 5. Zahl dann 6 Zahlen...; das geht mit Hilfe einer bestimmten Formel (Moivre-Binet Formel... hat mit dem Goldenen Schnitt zu tun... siehe Wikipedia bei Interesse;), auf die ich nicht näher eingehen möchte.

Mein Problem ist jetzt:

Die 43. Fibonacci Zahl ist: 433.494.437 (433 Millionen...), diese Zahl kann mein Script noch berechnen.
Die 44. Fibonacci Zahl ist: 701.408.733 (701 Millionen...), diese Zahl kann nicht mehr berechnet werden, bzw. als Ergebnis wird mir das hier ausgespuckt: 7,01408733E+8
Juhu -.- was soll ich mit "7,01408733E+8" ??

Wieso wird mir die 44. Zahl (und jede noch größere) mit so einem komische E+ und nem Komma dargestellt?

Kann man das irgendwie umwandeln in eine normale Dezimal-Zahl?

-----
So, hier mein Script Code:

Code:
set NatuerlicheZahl to display dialog "Mit diesem Script können die ersten 43 Fibonacci Zahlen errechnet werden. Gebe dazu eine (Natürliche) Zahl zwischen 0 und 43 ein!" default answer "" buttons {"abbrechen", "Fibonacci Zahl errechnen"} default button 2
-- Fenster öffnet sich und man muss eine (natürliche) Zahl zwischen 0 und 43 eingeben
if the button returned of the NatuerlicheZahl is "abbrechen" then
	-- wenn man abbrechen klickt ist das Script beendet, ...
else
	-- ...  klickt man hingegen auf berechnen wird folgender Code durchlaufen:
	set UserEingabe to text returned of NatuerlicheZahl
	-- Beginn der Berechnung der Fibonacci Zahl nach der Moivre-Binet Formel 
	set MoivreBinet to (1 / (5 ^ 0.5)) * (((1 + (5 ^ 0.5)) / 2) ^ UserEingabe) + 0.5
	-- Ende der Berechnung der Fibonacci Zahl nach der Moivre-Binet Formel (reine Mathematik;-)
	-- Für die 43. Fibonacci Zahl wird 433.494.437 (bereits ohne Nachkommastellen) als Ergebnis ausgegeben. Schon bei der 44. F-Zahl kommt 7,01408733E+8 als Ergebnis
	set ErgebnisMoivreBinet to MoivreBinet
	-- "ErgebnisMoivreBinet" -> Variable für das Ergebnis aus der Berechnung (mit der Moivre-Binet Formel). Dieses ist eine Zahl mit Nachkommastellen. Im Folgenden wird mit dem Befehl "set ... to ... div 1" einfach der Teil vor dem Komma als "Ergebnis_ohne_Nachkommastellen" definiert (man könnte die Zahl auch mit "round ErgebnisMoivreBinet rounding toward zero" ABrunden):
	set Ergebnis_ohne_Nachkommastellen to MoivreBinet div 1
	set Ausgabe to Ergebnis_ohne_Nachkommastellen
	-- einfach logische Namen vergeben
	display dialog "Die " & UserEingabe & ". Fibonacci Zahl ist " & Ausgabe buttons {"Autor", "Beenden"} default button 2
	if the button returned of the result is "Autor" then
		display dialog "Mit AppleScript geschrieben von Ludwig R. ([email protected]). Alle Rechte vorbehalten. Danke fürs Benutzen! Weitergabe (ohne Veränderung des Scripts) erlaubt. Verbessungsvorschläge bitte an die genannte E-Mail Adresse ;-)" buttons {"Programm beenden"} ¬
			default button 1
	end if
end if

Wie gesagt, ist nur mal so mein erster Versuch was in AppleScript zu schreiben :)
(Nein, ich will damit nicht berühmt werden, mein Name kommt t-dem rein^^)


Noch eine Frage am Rande: Habe auch so als Geck noch schnell einen Taschenrechner geschrieben^^:

Code:
set Recheneingabe to display dialog "Rechnung unten eingeben

Folgende Rechenoperationen sind dabei möglich:
+		Plus
-		Minus
*		Mal
/		Geteilt
^x		Hoch x
^(1/x)	x-te Wurzel

Für Nachkommastellen einen . verwenden (kein ,)" default answer "" buttons {"abbrechen", "berechnen"} ¬
	default button 2
if the button returned of the Recheneingabe is "berechnen" then
	set x to text returned of Recheneingabe
	set x to run script x & " as real"
	display dialog "Dein Ergebnis: " & x & " wurde in die Zwischenablage kopiert." buttons {"beenden"} ¬
		default button 1
	tell application "Finder" to set the clipboard to the ¬
		x as text
end if

Irgendwie bekomme ich diesen Befehl "tell application "Finder" to set the clipboard to the ¬ x as text" der im Taschenrechner super funktioniert nicht auch in meinen Fibonacci-Rechner... also ich möchte die errechnete Fibonacci-Zahl (im Script "Ausgabe" genannt) auch am Ende in der Zwischenablage haben.
Aber mit to set the clipboard to... Ausgabe as text funktioniert das nicht... Wieso bzw. wie funktioniert es?


Ich habe über Google schon folgendes gefunden: http://www.fischer-bayern.de/applescript/html/rundung.html
Da ist ganz unten ein Code mit dem man angeblich das mit dem E+ löst... der Code funktioniert allerdings bei mir nicht (hab den auch schon 1 zu 1 rauskopiert... liegt vielleicht daran, dass der Code aus dem Jahr 2005 !?)

Ich benutze den AppleScript Editor der bei Leopard (10.5.7) dabei war.



Vielen Dank !! =)


Mfg,
Ludwig
 

CloneOfMyself

Weigelts Zinszahler (Rotfranch)
Registriert
24.02.07
Beiträge
253
so sollte der Handler von Peter Fischer wieder funktionieren:

on TextConvert(dieZahl)
   set TextZahl to dieZahl as text
   if TextZahl contains "E+" then
      set x to offset of "," in TextZahl
      set y to offset of "+" in TextZahl
      set z to offset of "E" in TextZahl
      set Dezimal to text (y - (length of TextZahl)) thru -1 of TextZahl as string as number
      
      if x is not 0 then
         set Teil1 to text 1 thru (x - 1) of TextZahl as string
      else
         set Teil1 to ""
      end if
      
      set Teil2 to text (x + 1) thru (z - 1) of TextZahl as string
      set convZahl to Teil1
      repeat with i from 1 to Dezimal
         try
            set convZahl to convZahl & character i of the Teil2
         on error
            set convZahl to convZahl & "0"
         end try
      end repeat
      return convZahl
   else
      return TextZahl
   end if
end TextConvert

Es gibt aber (durch die Wandlung der Zahlen zu Strings bedingt) u.U. Ungenauigkeiten, da hierbei die letzten Stellen z.T. verschluckt und mit Nullen ersetzt werden, bevor das Komma wieder an seinen ursprünglichen Ort verschoben wird.

Beispiel:
set x to 2 ^ 50 --> 1.12589990684262E+15
set y to x as text --> "1,125899906843E+15"
 

harden

Roter Eiserapfel
Registriert
28.03.05
Beiträge
1.445
Die 44. Fibonacci Zahl ist: 701.408.733 (701 Millionen...), diese Zahl kann nicht mehr berechnet werden, bzw. als Ergebnis wird mir das hier ausgespuckt: 7,01408733E+8
Juhu -.- was soll ich mit "7,01408733E+8" ??

Scheinbar rechnet Apple Skript von Haus aus mit single precision Werten. Das sind 32bit für eine Zahl, wobei 1bit für Vorzeichen, 8bit für den Exponenten und die restlichen 23bit für die Mantisse. Ohne nachgerechnet zu haben würde ich einfach mal tippen, dass zwischen deiner 43 und 44. Zahl die Grenze der durch die Mantisse signifikant darstellbaren Stellen liegt und deshalb auf die Exponentendarstellung übergegangen wird.
Wenn du Apple Skript dazu veranlassen könntest auf double precision überzugehen, dann hättest du 52bit für die Mantisse.
 

Ludwig11

Granny Smith
Registriert
31.05.09
Beiträge
16
@CloneOfMyself: Danke für deine Mühe. Leider funktioniert der von dir ausgebesserte Handler mit zu großen Zahlen auch nicht mehr.
Das liegt aber dann vermutlich daran, was Harden geschrieben hat, mit den 32Bit.

Nachdem ich jetzt auf Wiki nachgelesen habe, was eine Mantisse ist, und was das mit den Bits auf sich hat, erscheint mir das auch halbwegs logisch.

Dann weiß ich jetzt zumindest, dass größere Zahlen auszurechnen kein Fehler im Script ist, sondern man einfach auf Grenzen stößt. So ganz 100% versteh ich das noch nicht, aber ich bin dabei es zu begreifen... Danke schön für eure Antworten, wieder ein Stückchen dazu gelernt : )

Wenn du Apple Skript dazu veranlassen könntest auf double precision überzugehen, dann hättest du 52bit für die Mantisse.

DAS scheint kompliziert zu sein... zumindest finde ich mit Google nicht wirklich etwas dazu im Konkreten (vielleicht such ich aber auch einfach nicht mit den richtigen Begriffen^^).
Auf Wikipedia hat ich dazu etwas gefunden... der IEEE-754-Standard.


Wie auch immer. Ich werde mich wohl doch noch mehr mit Lektüre über AppleScript beschäftigen müssen^^.
 

Ludwig11

Granny Smith
Registriert
31.05.09
Beiträge
16
Bin bis Samstag den 13. im Urlaub... dort gibt's leider kein Internet. Werde also nicht antworten können....
 

sedna

Galloway Pepping
Registriert
22.10.08
Beiträge
1.358
Hallo Ludwig!
Die Antwort von CloneOfMyself ist sehr informativ!
Allerdings hat er es etwas unglücklich in seinem ersten Satz ausgedrückt. Um es klarzustellen: Der Handler von Peter Fischer funktioniert auch in 10.5.7

Vorweg: Es ist natürlich toll, dass Du dich mit AppleScript beschäftigst, doch würde ich erst mal etwas kleiner anfangen. Du hast den Willen und wirst schnell Fortschritte machen.
So glaube ich, dass es momentan für dich schwierig werden wird, das Skript von CloneOfMyself in deines zu integrieren.
Aussagen wie "tell application "Finder" to set the clipboard to the ¬ x as text" lassen mich das vermuten...

Zurück zum Problem:

Du siehst, dass CloneOfMyself die Rundung herausgenommen hat.
Das "komische E" ist eine wissenschaftliche Notation, wie sie auch auf Taschenrechnern üblich ist. Sie hilft, große Zahlen handlich darzustellen. Grob erklärt: Das Komma muss um so viele Stellen nach rechts/links verschoben werden, wie die Zahl nach dem "E" anzeigt

Dem entsprechend ist dein Threadtitel nicht ganz richtig:
7,01E+8 = 701000000

Eine wichtige Sache möchte ich noch mal betonen: Bei wirklich LANGEN Zahlen werden tatsächlich "Stellen verschluckt".
Das heißt: Spätestens ab der 70sten (?) Fibonacci Zahl wird die ganze Angelegenheit für dich unbrauchbar
Probiere doch einfach mal, nur Zahlen zu kompilieren. Die 13te Stelle ist der Knackpunkt
(Du kannst in AppleScript z.B. auch nicht 1,2345678901234 schreiben. Oder probiere doch mal den Handler von CloneOfMyself mit 12345678901234)
Insgesamt lassen sich mit AppleScript, wie auch Spotlight oder dem Programm "Rechner" nicht mehr als 16 Stellen vor dem "E" darstellen

Du siehst: AppleScript ist wirklich nur bis zu einem gewissen Grad zum Rechnen geeignet.
Für die meisten Belange reicht es aber vollkommen aus :)

Allerdings kann man mit OSX auch sehr lange Zahlen rechnen.
Wenn Du dich weiter mit AS beschäftigst, so wirst Du früher oder später auch die Möglichkeit nutzen, shell scripte auszuführen.
Öffne das Programm Terminal, tippe "man bc" ein und lese, was dort steht.
Auch damit wirst Du ab Zahlen über 68 Stellen einen "Umbruchstrich" erhalten, der aber nur auf Grund der besseren Darstellung eingeführt wurde (Und den Du theoretisch mit AS entfernen kannst)

Doch wer will wirklich solche langen Zahlen lesen bzw. darstellen?

Um dich anzufüttern, ein kleines Beispiel (den Rest mußt Du dir selber basteln! :-* )

Code:
set dd to display dialog "Rechne 3 * (4 ^ x) !" & return & " Gebe den Wert für x ein:" default answer ""
set x to text returned of dd

set res to do shell script "echo '3 * (4 ^" & x & ")' | bc"

tell application "Finder" to set the clipboard to res
display dialog res

Sedna
 

CloneOfMyself

Weigelts Zinszahler (Rotfranch)
Registriert
24.02.07
Beiträge
253
hallo sedna.

auf bc hatte ich das obige beispielscript auch schon mal umgefrickelt. da kam aber immer nur mist (immer das gleiche ergebnis) heraus. kann allerdings sein, dass ich noch einen fehler drin hatte...
ich muss allerdings gestehen, dass ich auch nicht weiss, was wirklich rauskommen sollte ;) vielleicht stimmt der code oben von ludde ja auch nicht...

nee, liegt wohl am 5 ^ 0.5 - das schnappt bc wohl nicht. der exponent muss integer sein.
 
Zuletzt bearbeitet:

sedna

Galloway Pepping
Registriert
22.10.08
Beiträge
1.358
nee, liegt wohl am 5 ^ 0.5 - das schnappt bc wohl nicht. der exponent muss integer sein.

Hallo CloneOfMyself! :)

Solltest Du etwa man bc nicht gelesen haben? :p

expr ^ expr
The result of the expression is the value of the first raised to the second. The second expression must be an integer. (If the second expression is not an integer, a warning is generated and the expression is truncated to get an integer value.)
[…]
It should be noted that expr^0 will always return the value of 1.
Dem entsprechend die Warnung
Runtime warning: non-zero scale in exponent for a fractional part of an exponent that is being ignored.
Ein echter Mathematiker stellt die Formel dem entsprechend um. Ich (räusper) bin da leider der falsche Ansprechpartner :eek: ... aber ein bisschen kann ich noch an Halbwissen loswerden:
5^0.5 = √5 . Dafür gibt es in bc die Funktion sqrt.
√5 würde deinen Rechner bis zum Sankt Nimmerleinstag rechnen lassen. bc verlangt deshalb von dir Angaben, auf wie viel Stellen genau es das rechnen soll:
Code:
scale=10000; sqrt (5)
Also schön die Formel umschreiben und fertig! :p
Ich bin da ja nicht schlau genug für, würde es aber eh auf die praktische Art lösen:

So! Jetzt kommt ein Spoiler! (Text markieren, um ihn zu lesen)
Ludwig! Du wirst den schön brav NICHT lesen, sondern DEINE Lösung finden!
Erst wenn alle Nägel abgekaut sind, die Bude von deinem rauchenden Kopf vernebelt ist und deine Tastaur vom Kopfabrollen geschliffen ist, kannst Du ja mal schmulen :-*



- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Den eingebauten Handler im Skript habe ich von dieser Site:
<http://hohabadu.de/?APPLESCRIPT>
Die kann ich dir nur wärmstens empfehlen!

set dd to display dialog "Fibonucci Zahl" default answer ""
set x to text returned of dd
set fibo to do shell script "echo '(0.4472135955 * (1.61803398875 ^ " & x & ") + 0.5)/1;' | bc"


set srchList to {return, "\\"}
set replList to {""}

repeat with i from 1 to (count of srchList)
set srch to item i of srchList
set replList to every text item of replList
set AppleScript's text item delimiters to srch
set the temp to every text item of fibo
set AppleScript's text item delimiters to replList
set fibo to temp as string

set AppleScript's text item delimiters to ""
end repeat
display dialog fibo




Sedna
 
Zuletzt bearbeitet:

CloneOfMyself

Weigelts Zinszahler (Rotfranch)
Registriert
24.02.07
Beiträge
253
Respekt, Respekt, Sedna... :cool:
"Anholn deit kriegen..." würde der Friese sagen ;)
 

Ludwig11

Granny Smith
Registriert
31.05.09
Beiträge
16
So, bin wieder vom Urlaub zurück.

Danke für die vielen informativen Antworten !
"scale=10000; sqrt (5)" anstatt der Schreibweise 5^0.5 - sehr praktisch! Dankeschön :)
Werde schön weiter lernen und wohl noch ein paar Bücher lesen.
Macht irgendwie Spaß =) *g*


Grüße,
Ludwig