5

Ich versuche, einfache Subtraktion Arithmetik auf zwei sehr große Zahlen zu tun.Wissenschaftliche Notation Umwandlung - Schema

(- 1.8305286640724363e+023 (floor 1.8305286640724363e+023)) 

Wenn ich dies tue, bekomme ich ein Ergebnis von 0,0. Ich erwarte eine Ausgabe von:

(- 1.8305286640724363e+023 (floor 1.8305286640724363e+023)) => .2439521 

Die erweiterte wissenschaftliche Notation würde mir diese Antwort geben.

183052866407243622723319,24395251 - 183052866407243622723319,00 = .2439521

Ich mag diese Zahlen darzustellen, wie sie sind, mit den Dezimalzahlen vorhanden, im Gegensatz zu wissenschaftlicher Notation, also kann ich das gewünschte Ergebnis erzielen. Gibt es eine Möglichkeit, dies innerhalb von Scheme zu tun? Jede mögliche Hilfe, Anleitung oder Referenz würde sehr geschätzt werden :)

Ich benutze DrRacket für Windows 64bit und R5RS Sprache.

EDIT

Ich dachte, ich wie möglich in Bezug auf ein Beispiel thearithmetic als spezifisch sein würde ich durchführen werde.

Arithmetik:

(* 271979577247970257395 0.6180339887) => 1.6809262297150285e+020 

Wenn in einem Rechner das gleiche Multiplikation zu tun, ist das Ergebnis yeilds => 168092622971502827156,7975214365

Beim Versuch, genau zu verwenden oder ungenauen ich diese:

(exact (* 271979577247970257395 0.6180339887)) => exact: undefined; 
(inexact (* 271979577247970257395 0.6180339887)) => inexact: undefined; 

Ich nehme an, R5RS unterstützt nicht genau/ungenau? Ich sah es auf und Beispiele zeigen die Verwendung inexact-> genaue Vorgehensweise also tat ich und bekam dies:

(inexact->exact (* 271979577247970257395 0.6180339887)) => 168092622971502854144 

Und nur für die Spezifität, habe ich das Gegenteil:

(exact->inexact (* 271979577247970257395 0.6180339887)) => 1.6809262297150285e+020 

So dann habe ich versucht, mit Big Float als jemand erwähnt:

(bf-precision 128) 
(bf (* 271979577247970257395 0.6180339887)) => (bf 168092622971502854144) 

Geben Sie mir die gleiche Ausgabe wie genau. Alles, was ich will, ist nur die Nummer zu bekommen, die ich von einem Taschenrechner bekommen würde und es scheint eine sehr schwierige Aufgabe zu sein! Es tut mir leid, dass ich mich dumm anhören mag, weil ich das nicht verstanden habe. Behalte im Hinterkopf, dass ich in SCHEME ein extremer Amateur bin. Danke nochmal für deine Hilfe! :)

Antwort

4

Das Problem ist, dass Sie mehr signifikante Ziffern in der Eingabe haben als Racket verwendet in seiner internen Darstellung.

Lassen Sie uns die nackten Zahlen eingeben:

> 183052866407243622723319.24395251 
1.8305286640724363e+23 

> 183052866407243622723319.00 
1.8305286640724363e+23 

Beide Zahlen sind somit als gleich (ganze) Zahl intern vertreten. Dies erklärt, warum Ihr Ergebnis 0 war.

Dieses Verhalten ist nicht auf Racket beschränkt. Tatsächlich folgt Racket dem IEEE-Standard für das Rechnen mit 64-Bit-Fließkommazahlen.Sie erhalten dasselbe Ergebnis in anderen Programmiersprachen.

Wenn Sie berechnen müssen, warum größere Präzision, können Sie stattdessen bigfloats verwenden.

(require math/bigfloat) 
(bf-precision 128) ; use 128 bits 
(bf- (bf #e183052866407243622723319.24395251) 
    (bfround (bf #e183052866407243622723319.00))) 

Das Ergebnis ist: (bf # e0.2439525099999997337363311089575290679932)

Hinweis: Zur Nutzung bigfloats sicherstellen, dass Sie eine aktuelle Version von Racket haben.

Update: Falls Sie sich fragen, warum das Ergebnis nicht war .2439521 die Antwort ist, dass das Ergebnis und .2439521 durch das gleiche interne Bitmuster dargestellt wird.

Update:

Wenn Sie das Ergebnis wieder in ein Standard-Floating-Point machen wollen, bigfloat->flonum verwenden.

(bf-precision 256) ; to get more decimal digits correct 
(bigfloat->flonum 
    (bf- (bf #e183052866407243622723319.24395251) 
     (bfround (bf #e183052866407243622723319.00)))) 

Dies gibt das Ergebnis: 0,24395251

Nachtrag:

Racket (und Scheme) liest Zahlen mit Dezimalstellen als Gleitkommazahlen. Wenn Sie eine Zahl mit #e voranstellen, wird sie als exakte Zahl gelesen (dh der resultierende Wert ist ein exakter Bruch). Sie können damit die genauen Dezimalstellen beibehalten. Sie geben die genauen Zahlen für Ihre gesamte Berechnung an und verwenden dann am Ende exact->inexact, um das Ergebnis in eine Fließkommazahl umzuwandeln. Hier ist Ihr Beispiel:

> (exact->inexact 
    (- #e183052866407243622723319.24395251 
     #e183052866407243622723319.00)) 
0.24395251 
+0

Hallo, vielen Dank für Ihre schnelle Antwort! Der Bigfloat gibt mir nicht die Dezimalstellen, die ich möchte. Ich sehe, dass Sie ihm die Dezimalstellen mit Nachdruck mitteilen und dann die Subtraktion durchführen. Ich mache Arithmetik, um die Fließkommazahl zu erhalten. Ich werde die Frage aktualisieren, damit ich es dir zeigen kann. – Sixers17

+0

Hallo. Ich habe ein Update hinzugefügt, das zeigt, wie man das Ergebnis wieder in eine Standard-Fließkommazahl umwandelt. – soegaard

+0

Ich habe eine Alternative zur Verwendung von bigfloats hinzugefügt. – soegaard

4

Natürlich Schema Sie genaue Zahlen haben:

(define x (+ (exact 183052866407243622723319) (exact .24395251))) 
(define y (+ (exact 183052866407243622723319) (exact .0))) 

I gespalten x zu vermeiden, das Schema mit Leser den Wert gestutzt. Dann:

> x 
3297587283763054256749149618043779713285/18014398509481984 
> (- x y) 
4394657732528389/18014398509481984 
> (inexact (- x y)) 
0.24395251 

[bearbeiten] Sie müssen genaue Zahlen während der Berechnung verwenden. Das bedeutet, konvertieren Sie Ihre Eingabe in genau und dann am Ende konvertieren Sie Ihre Ausgabe in ungenau (falls gewünscht).

Wie für Ihren Versuch #e(* 27... 0.6...) - das wird nicht funktionieren, weil die #e gilt für Zahlen, nicht Ausdrücke. Verwenden Sie (* #e27... #e0.6...).

> (* #e271979577247970257395 #e0.6180339887) 
336185245943005654313595042873/2000000000 
+0

Du fügst die Dezimalstelle explizit zu der großen Zahl hinzu.Obwohl dieses Beispiel mich über einige Dinge aufklärte, die ich nicht über die Verwendung von ungenau und ungenau wusste, versuche ich, diese Dezimalzahl durch Arithmetik zu erzeugen. Siehe mein Update. Danke für die Antwort! – Sixers17

+0

Ich habe die Dezimalstelle explizit hinzugefügt, denn wenn ich sie einfach als Fließkommazahl eingegeben habe, wäre es zu spät, wenn ich 'exact' angewendet hätte. Lösung dafür ist die Verwendung von '# e' als Präfix für die Nummer selbst. Hinweis: Siehe oben Bearbeiten. – GoZoner

+0

Vielen Dank für das Update! Ich habe einen Weg gefunden, dies mit deiner Hilfe zu tun! Vielen Dank GoZoner! – Sixers17

Verwandte Themen