Ungenauigkeit von Long-Werten in JavaScript

Mit Java generierte Long-Zahlen können auf einem 64-Bit-Betriebssystem einen Maximalwert von 9223372036854775807 annehmen. Diese 19-stellige Zahl kann von einem JavaScript-Client jedoch nicht verarbeitet werden.

JavaScript ist, im Gegensatz zu Java, nicht streng typisiert und kennt für numerische Werte nur den Datentyp Number. Der Datentyp Number ist mit 64-Bit (8 Bytes) zwar ausreichend groß, jedoch müssen in diesen 64-Bit auch Fließkommazahlen abgebildet werden. Deshalb können in JavaScript mit diesen 64-Bit nicht so viele Ganzzahlen dargestellt werden, wie mit dem 64-Bit Long-Datentyp aus Java (welcher nur Ganzzahlen abbilden muss). Zahlen in JavaScript sind daher nur bis zur 15. Stelle genau.

Folgendes Beispiel verdeutlicht das Problem:

1
2
3
var longNumber = 9223372036854775807;
console.log(longNumber); // 9223372036854776000 (inaccurate!)
console.log(typeof(longNumber)); // number

Diese Ungenauigkeit kommt auch zum Tragen, wenn versucht wird eine JSON-Zeichenkette in ein JavaScript Objekt (JSO) zu konvertieren:

1
2
3
4
var json = '{"name":"Benny Neugebauer","id":9223372036854775807}';
var jso = JSON.parse(json);
var id = jso['id'];
console.log(id); // 9223372036854776000

Möchte man die Long-Werte korrekt darstellen, so empfiehlt es sich, die Zahl als String (und nicht als Number) zu verarbeiten. Dazu muss die Zahl in Gänsefüßchen geschrieben werden. Der folgende Code nimmt diese Umwandlung vor:

1
2
3
4
5
6
7
8
9
10
11
var json = '{"name":"Benny Neugebauer","id":9223372036854775807}';
var replace = json.replace(/(\:|[\:\[])(\d+?)([},\]])/g,'$1"$2"$3');
var jso = JSON.parse(replace);
var id = jso['id'];
console.log(typeof(id)); // string
console.log(id); // 9223372036854775807 (correct!)
 
console.log(json);
// {"name":"Benny Neugebauer","id":9223372036854775807}
console.log(replace);
// {"name":"Benny Neugebauer","id":"9223372036854775807"}

Interessanter Artikel: The Complete Javascript Number Reference

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.