2009-07-13 5 views
3

Ich habe einen string:Converting JSON String-Objekt mit selektiver Auswertung

"{0:16970861903381446063,length:1}" 

ich versuchte, es auf ein Objekt mit Hilfe der eval Umwandlungsverfahren, aber es wertet auch die Zeichenfolge und damit rundet den Zahlenwert, Return:

{0:16970861903381447000,length:1} 

I versucht, die Zahl als Zeichenfolge vorbei vor dem Aufruf eval sie darauf 16970861903381446063 + '' als Wert zu verwenden, wenn die JSON Zeichenkette erzeugt wird; Prüfen Sie es mit typeof zeigt es als Typ zu sein string, aber es rundet noch die Nummer 16970861903381446063 zu 16970861903381447000.

Gibt es eine Weise, die ich dies umgehen kann, oder einen besseren Weg, dies zu tun?

Es folgt der Code, der die json Text aus einem Array mit den Zahlen

function simplify(arr){ 
     request = "{"; 
     if (arr.length ==1){ 
     request += 0 + ":" + (arr[0] + '') + "," ; 
     } 
     else{ 
     for (var i=0;i<=arr.length-1 ;i++){ 

     request += i + ":" + (arr[i] + '') + ","; 
    } 
    } 
    request += "length" + ":" + arr.length +"}"; 
    return request; 
} 

Antwort

3

Sie laufen gegen die Präzision eines IEEE-Double-Precision-Schwimmer, und fügte hinzu, die 53 Bits für die Mantisse verwendet und 11 Bits für der Exponent.

Javascript-Nummern, ALLE von ihnen, werden durch 64-Bit-Fließkommazahlen dargestellt. Fließkommazahlen in vielen Sprachen werden durch zwei Teile repräsentiert, eine Mantisse und einen Exponenten. In Javascript beträgt die Mantisse 53 Bits und der Exponent 11 Bits.

Wenn Sie Zahlen sehen, ausgedrückt als zum Beispiel 3.5346367e + 22 ist die Mantisse 3,5246367 und der Exponent 22.

Die Zahlen, die Sie zu speichern versuchen, sind größer als der Maximalwert der Mantisse , so werden Ihre Zahlen gerundet und größere Zahlen erhalten einen Exponenten.

Lange Rede, kurzer Sinn: Wenn Sie mit diesen riesigen Zahlen keine arithmetischen Operationen durchführen, sollten Sie sie als String speichern.

Schließlich sollten Sie ausgedrückt JSON Arrays als tatsächlicher JSON Arrays und nicht als Objekte, die durch die Definition von Integer-Schlüssel und eine Länge Eigenschaft sein Arrays vorgeben:

// Do this 
json = '["16970861903381446063"]'; 

// Not this 
json = '{0:"16970861903381446063", length:1}'; 
+0

Danke für die Bestätigung. FP ist böse. –

2

Klingt wie Sie es erzeugt einen String den ganzen Weg durch brauchen zu halten. Aber wenn Sie das tun, wie wollen Sie damit rechnen?

+1

Nun, das ist das Problem, ich war in der Bypass-Hoffnung, Parsen, indem Sie es zu einem String machen, der dann auf der Serverseite, auf der die Berechnung durchgeführt wird, in den Integer-Wert umgewandelt wird. – Amit

+1

Ich vermute, das Problem ist, dass die Zahl zu groß ist, um als Ganzzahl verwendet zu werden, und wird stattdessen als Float behandelt. Schwimmer haben eine große Reichweite, aber sie nähern sich an. –

+0

Lassen Sie mich hinzufügen, dass, wenn dies der Fall ist, die Antwort besteht darin, die Ziffernfolge von rechts beginnend aufzulösen und sie in einer Gruppe von Ganzzahlen zu speichern. –

3

einfach wickeln Sie es in Anführungszeichen eine Zeichenfolge zu machen:

{ 
    0: "16970861903381446063", 
    length: 1 
} 

Ich nehme an, Sie sind gerade diese irgendwo im Dokument verwendet wird; Oder planen Sie, es als tatsächliche Nummer zu verwenden?

+1

Ja, ich möchte es als eine Nummer (auf der Serverseite) verwenden, aber ich kann mir keine andere Möglichkeit vorstellen, die Evaluierung zu umgehen und dann in eine Zeichenfolge umzuwandeln. – Amit

0

Ordnung fand eine einfache Lösung dank Leuten bei freenode

function simplify(arr){ 
     request = "{"; 
     if (arr.length ==1){ 
      request += (0 + ":" + "'" + String(arr[0])+ "'" + ",") ; 
     } 
     else{ 
      for (var i=0;i<=arr.length-1 ;i++){ 
      request += i + ":" + "'" + String(arr[i]) + "'" + ","; 
     } 

    } 
     request += "length" + ":" + arr.length +"}" ; 
return request; 
    } 

Problem mit eval war, obwohl ich war mit Stringliterale mit Array sie waren Zahlen und eval eine Schnur benötigt, die nicht eval sein könnte() "Ed.

Es folgt die Probe ausgegeben, nachdem ausdrücklich zitiert zu den Saiten

{0:'16970861903381446063',1:'16970861903381444012',length:2} 
+0

Richtig, die großen Zahlen als Strings übergeben vermeidet Parsing-Probleme. Aber müssen Sie diese Zahlen auf der Clientseite jemals mathematisch berechnen oder nur anzeigen? –

+0

Auch Triptych's Punkt über das Serialisierungsformat ist tot. –

+0

Ja, sie werden auf der Server-Seite verarbeitet, daher funktioniert es jetzt gut, wenn sie als Zeichenfolgen verwendet werden. Danke nochmal Jungs. – Amit