Ich schreibe ein Programm, das rohe doppelte Werte aus einer Datenbank nimmt und sie in 8-Byte Hex-Strings konvertiert, aber ich weiß nicht, wie man Genauigkeitsverlust verhindern kann. Die von allen Geräten empfangenen Daten werden doppelt gespeichert, einschließlich der 8-Byte-Identifikationswerte.Wie vermeide ich Genauigkeitsverlust mit Double in Java?
Instanzen von Doppelpunkten wie 7.2340172821234e + 16 werden korrekt ohne Genauigkeitsverlust analysiert, wobei der Exponent 10^16 ist.
In Fällen jedoch, in denen der Exponent 10^17 ist, verliert Java die Genauigkeit. Zum Beispiel 2.88512954935019e + 17 wird von Java als 1.44464854248327008E17
interpretiert Der Code, den ich wie folgt aussieht bin mit:
public Foo(double bar) {
this.barString = Long.toHexString((long) bar);
if (barString.length == 15) {
barString = "0" + barString; //to account for leading zeroes lost on data entry
}
}
ich dies einen Testfall ähnlich wie verwende es zu testen:
@Test
public void testFooConstructor() {
OtherClass other = new OtherClass();
OtherClass.Foo test0 = other.new Foo(72340172821234000d); //7.2340172821234e+16
assertEquals("0101010100000150", test0.barString); //This test passes
OtherClass.Foo test1 = other.new Foo(144464854248327000d);//1.44464854248327e+17
assertEquals("02013e0500000758, test1.barString); //This test fails
}
Die Unit-Test lautet:
Expected: 02013e0500000758
Actual: 02013e0500000760
Wenn ich p rucken aus den Werten, die Java gespeichert 72340172821234000d und 144464854248327000d wie es jeweils druckt:
7.2340172821234E16
1.44464854248327008E17
Dieser Wert ist um 8 ab, die für die konsistent zu sein scheint Wenige, die ich getestet habe.
Kann ich irgendetwas tun, um diesen Fehler zu korrigieren?
EDIT: Dies ist kein Problem, wo mich interessiert, was ist vorbei an der Stelle. Die Frage, von der einige denken, dass es sich um ein Duplikat handelt, lautet, warum Fließkommazahlen weniger präzise sind. Ich frage, wie man den Verlust von Genauigkeit vermeiden kann, und zwar durch ähnliche Umgehungslösungen wie die, die Roman Puchkovskiy vorgeschlagen haben.
Sie können nicht. 'double' hat eine begrenzte Genauigkeit. –
Versuchen Sie mit BigDecimal – DwB
@DwB Oder, wenn es eine ganze Zahl ist, BigInteger. – Dukeling