Domino 9 und frühere Versionen > ND6: Entwicklung
Datum und Zeitbrechnung
Marinero Atlántico:
Der Trick ist, dass du festlegen kannst nach wie vielen Stellen hinter dem Komma gerundet wird (mit scale-property). Ausserdem kannst du die Rundungsmethode wählen.
Präferiere: "auf eine klar definierte Art und Weise entschärft" gegenüber "etwas entschärft" ;D. Es ist schon klar, dass man 1/3 nicht wirklich genau als Dezimalzahl oder Binärzahl wiedergeben kann.
Wobei ich mir bei einem Beispiel gerade in den Fuß geschossen habe:
Es zeigt genau das umgekehrte von dem, was ich beweisen wollte ::)
--- Code: ---// use ide to import classes
public class ASimpleMathQuestion {
public static void main(String[] args) {
System.out.println("a simple math task for my computer...\na) using double: (1 / 3) * 3=" + ((1/3) + 3));
System.out.print("a simple math task for my computer...\nb) using BigDecimal: (1 / 3) * 3=");
BigDecimal anOne = new BigDecimal(1);
BigDecimal aThree = new BigDecimal(3);
System.out.println(aThree.multiply(anOne.divide(aThree, 100, BigDecimal.ROUND_HALF_DOWN)));
}
}
--- Ende Code ---
Ergibt:
--- Code: ---a simple math task for my computer...
a) using double: (1 / 3) * 3=3
b) using BigDecimal: (1 / 3) * 3=0.9999999999999999999999999999999999999999
--- Ende Code ---
Naja. Es ist eine andere Art von Unschärfe. Muß das wohl noch ein bischen üben mit BigDecimal. Ich kann mich dunkel daran erinnern, dass in Finanzmathematik intern auf 5 Stellen hinter dem Komma gerechnet wird und auf 2 oder 3 Stellen hinter dem Komma angezeigt wird.
Wenn man den Anzeigewert setScale(scaleInter-1) gibt gehts:
--- Code: ---public class ASimpleMathQuestion {
public static void main(String[] args) {
System.out.println("a simple math task for my computer...\na) using double: (1 / 3) * 3=" + ((1/3) + 3));
System.out.print("b) using BigDecimal: (1 / 3) * 3=");
BigDecimal anOne = new BigDecimal(1);
BigDecimal aThree = new BigDecimal(3);
int scale = 40;
System.out.println(aThree.multiply(anOne.divide(aThree, scale, BigDecimal.ROUND_HALF_DOWN)).setScale(scale-1, BigDecimal.ROUND_HALF_DOWN));
}
}
--- Ende Code ---
ergibt:
--- Code: ---a simple math task for my computer...
a) using double: (1 / 3) * 3=3
b) using BigDecimal: (1 / 3) * 3=1.000000000000000000000000000000000000000
--- Ende Code ---
Marinero Atlántico:
--- Zitat von: Semeaphoros am 12.06.05 - 12:09:25 ---Was bei Oracle der Decimal-Datentyp genau ist,
--- Ende Zitat ---
Imho ist es ein SQL92 Datentyp. Ist nicht Oracle spezifisch.
--- Zitat ---weiss ich nicht. Ich vermute mal, dass es sich um einen BCD-Datentyp handelt.
--- Ende Zitat ---
Es ist - wie BigDecimal - nicht floating point.
Man gibt die Anzahl der Ziffern hinter dem Komma fix an und gleichzeitig die Regeln für die Rundung (s. mein Beispiel f. BigDecimal).
--- Zitat ---Und -- in LotusScript bzw. Notes/Domino gibts den Typ nicht, kommt also geradezu nicht in Frage.
--- Ende Zitat ---
Meine Idee ist, diesen Datentyp nachzuprogrammieren, was geht.
TMC:
--- Zitat von: Semeaphoros am 12.06.05 - 11:06:55 ---im Speziellen für Zeit und Datum spricht das ganze dafür die NotesDateTime Klasse zu verwenden, anstatt die Berechnungen direkt am Zeitwert durchzuführen, in der Hoffnung, dass die interne Implementation dieser Klasse die Problematik so weit wie möglich berücksichtigt.
--- Ende Zitat ---
--- Zitat von: Thomas Völk am 12.06.05 - 11:34:40 ---ich sehe ehrlich gesagt keinen Grund, nicht die NotesDateTime-Klasse zu benutzen.
--- Ende Zitat ---
Bis gestern war ich eigentlich der Meinung, für so simple Dinge braucht man die Klasse nicht.
Aber aufgrund der hier geschilderten Probleme werde ich zukünftig sicherlich primär die DateTime-Klasse benutzen (oder eine eigene Klasse, die auf die DT-Klasse aufsetzt), und nicht mehr eigenständig hier rumhantieren, die Gefahr ist wohl zu groß, dass da was schief läuft, und prinzipiell muss man sich auf die DT-Klasse auch verlassen können (wie eben auf jede andere Klasse auch – Bugs sind natürlich nie ganz auszuschließen).
Matthias
Marinero Atlántico:
Es haben sich hier verschiedene Themen vermischt. Wobei ich daran natürlich nicht ganz unschuldig bin.
Das mit Bernhards Rundungsfehler hat ja nicht unbedingt etwas mit Zeit und Datumsberechnung zu tun, sondern mit seiner speziellen Implementierung einer Lösung und der sich daraus ergebenen Problematiken.
Das mit der fixen Anzahl an Stellen hinter dem Dezimalpunkt ist aber auch ein wichtiger Punkt. Zumindest für mich. Deshalb werd ich eine entsprechende fixedDecimalPointMath Klasse mal erstellen.
@Jens: ich hab noch mal gegoogelt. Das hat wirklich nix mit BCD-Datentyp zu tun.
Wenn ich die entsprechende Klasse geschrieben habe, wird das - denke ich - klar.
LotusScript hat übrigens einen numerischen "fixed point" Datentyp. Currency. Selten benutzt, aber das ist die Richtung, die ich meine.
Axel
Semeaphoros:
Sorry, Axel, Currency ist Float mit einer besonderen Darstellungsart, genauso wie Deine Math-Klasse am Schluss schlichtweg eine Extension zu einem bestehenden, anderen Datentyp sein wird. Currency wird intern genau gleich wie Float repräsentiert.
Navigation
[0] Themen-Index
[#] Nächste Seite
[*] Vorherige Sete
Zur normalen Ansicht wechseln