Umgang mit Rundungsfehlern<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />Ich habe dieses Skript, das eine einfache Berechnung durchführt und das Ergebnis in einem Fenster anzeigt:
Zwischensumme = 100.05 ;
RabattProzent = 0,1 ;
RabattBetrag = Zwischensumme * RabattProzent;
totalBeforeTax = subtotal - discountAmount;
formatierteNachricht = Konkat (
"Zwischensumme:" , Wiederholen ( " " , 5 ), Format (Zwischensumme, "Währung" ), "\!N" ,
"Rabattprozentsatz:" , Wiederholen ( " " , 5 ), Format (RabattProzent, "Prozent" ), "\!N" ,
"Rabattbetrag:" , Wiederholen ( " " , 5 ), Format (Rabattbetrag, "Währung" ), "\!N" ,
"Gesamt vor Steuern:" , Wiederholen ( " " , 5 ), Format (Gesamt vor Steuern, "Währung" ), "\!N"
);
formattedMessageDisplay = Neues Fenster ( "Ergebnis" ,
Lineup-Box ( N Spalte ( 1 ), Abstand ( 0 , 0 ), Border-Box ( Links ( 20 ), Rechts ( 20 ), Spitze( 20 ), Unterseite( 20 ),
Textfeld ( formatierte Nachricht, << SetFontSize ( 14 ) ) )
),
Zeigen (Zwischensumme, Rabattbetrag, Summe vor Steuern)
);
Es erzeugt Folgendes im Protokoll und im Ausgabefenster:



Also verwenden Format (Gesamt vor Steuern, "Währung" ), Ergebnisse insgesamt vor Steuern, die "aufgerundet" werden. Ich kann mir eine Vielzahl von Möglichkeiten vorstellen, damit umzugehen, aber ich fragte mich, was am meisten zu empfehlen wäre.
Re: Umgang mit RundungsfehlernDerzeit keine Big Number-Pläne.Im StackOverflow-Link wurden viele interessante Punkte gemacht.Je nachdem, was Sie mit den Zahlen machen, können unterschiedliche Lösungen geeignet sein.
Craige
Re: Umgang mit RundungsfehlernEine andere Sache, an die ich dachte, war, in String zu konvertieren und Regex zu verwenden.
Re: Umgang mit RundungsfehlernDanke Craige, in der Tat habe ich darüber nachgedacht, eine Schnittstelle zu erstellen, um JMP den Zugriff auf die BigDecimal-Klasse von Java zu ermöglichen. Gibt es Pläne, dies als Typ in die nächste Version von JMP aufzunehmen?
Re: Umgang mit RundungsfehlernMöglicherweise möchten Sie die Berechnung des Rabattbetrags runden/Untergrenze/Obergrenze.Round hat ein zweites Argument, das Sie für Nachkommastellen möglicherweise auf 2 setzen möchten.Boden und Decke benötigen etwas wie floor(x*100)/100, um ein ähnliches Ergebnis zu erzielen.
Zwischensumme = 100,05;
RabattProzent = 0,1;
RabattBetrag = runden (Zwischensumme * RabattProzent, 2) ;
totalBeforeTax = subtotal - discountAmount;
show(discountAmount, totalBeforeTax);
Rabattbetrag = 10,01;
GesamtvorSteuer = 90,04;
Die Formatfunktion in Ihrem Originalcode ist auf der Messerschneide des Auf- oder Abrundens, wobei 0,005 auf zwei Stellen gerundet wird.Die Diskrepanz in der Darstellung wird dadurch ausgelöst, dass der Wert in einem Fall ein Minus und in dem anderen ein Plus hat ... beide Werte werden aufgerundet, aber einer von ihnen hat einen negativen Rabattbetrag in der Berechnung.
In JMP verwendete Gleitkommazahlen stellen Zahlen wie 0,01 als abgeschnittenen, sich wiederholenden Binärbruch dar.Genauso wie 1/3 nicht genau 0,333333333333 ist, ist die interne Darstellung nicht exakt (außer bei binären Brüchen wie 1/2, 1/4, 1/8, ...). Wenn Sie 100 Pfennige addieren, die als 0,01 dargestellt werden, erhalten Sie eine Zahl, die sehr nahe an 1,00 liegt, sich jedoch an der 16. Dezimalstelle unterscheidet.Dieser sehr kleine Fehler hat immer dazu geführt, dass Buchhaltungspakete eine andere Darstellung gewählt haben: java - Warum nicht Double oder Float verwenden, um eine Währung darzustellen? - Paketüberfluss
Gesamt = 0;
For( i = 1, i <= 100, i++, insgesamt += 0,01 );
show(format(total,"fixed",20,16) );
Format(gesamt, "fest", 20, 16) = "1.0000000000000007";
Re: Umgang mit RundungsfehlernHallo Jim,
Danke für deine Antwort. Floor und Ceiling runden also auf die nächste ganze Zahl. Das Format (x, „Währung“) scheint grundsätzlich Round(x,2) zu verwenden. Man könnte meinen, das Format "Währung" würde eher eine Trunkierungsmethode als eine Rundung verwenden.
Re: Umgang mit RundungsfehlernIch mache nicht viel Finanzberichte, aber wenn ich mich um Rundungsfehler kümmern muss, verwende ich einfach die Funktionen Round(),Ceiling() und Floor().