views:

366

answers:

4

I have a string:

"{0:16970861903381446063,length:1}"

I tried converting it to an object using the eval method, but it also evaluates the string and hence rounds the numerical value, returning:

{0:16970861903381447000,length:1}

I tried passing the number as a string before calling eval on it, using 16970861903381446063 + '' as the value when creating the JSON string; checking it with typeof shows it as being of type string, but it still rounds the number 16970861903381446063 to 16970861903381447000.

Is there a way I can bypass this, or a better way to do this?

Following is the code that generates the json text from an array containing the numbers

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;
 }
+2  A: 

Sounds like you need to keep it a string the whole way through. However, if you do that, how do you plan to do any math with it?

Steven Sudit
Well that's the problem, i was hoping to bypass parsing by making it a string then casting it back to integer on the server side where the calculation is being done.
Amit
I suspect the problem is that the number is too big to be used as an integer and is instead being treated as a float. Float's have a large range, but they approximate.
Steven Sudit
Let me add that, if this is the case, the answer is to break the digit string up, starting from the right, and store it in a set of integers.
Steven Sudit
Can you please elaborate ? May be with a small example ?
Amit
+3  A: 

Just wrap it in quotes to make a string:

{
    0: "16970861903381446063",
    length: 1
}

I'm assuming you're just using this somewhere within the document; or are you planning to use it as an actual number?

J-P
Yes i want to use it as a number (on the server side), but i can't think of any other way to bypass evaluation then converting to string.
Amit
A: 

Alright found an easy solution thanks to folks at 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 was with eval, even though i was using array with string literals they were numbers and eval needed some string which could not be eval() 'ed.

Following is the sample output after explicitly adding quotes to the strings

{0:'16970861903381446063',1:'16970861903381444012',length:2}
Amit
Right, passing the big numbers as strings avoids parsing issues. But do you ever need to do math on these numbers on the client side or just display them?
Steven Sudit
Also, Triptych's point about the serialization format is dead on.
Steven Sudit
Yes they are processed on servers side, so it works fine now using them as strings. Thanks again guys.
Amit
+3  A: 

You're running up against the precision of an IEEE double-precision float, which uses 53 bits for the mantissa and 11 bits for the exponent.

Javascript numbers, ALL of them, are represented by 64-bit floating point numbers. Floating point numbers in many languages are represented by two parts, a mantissa and an exponent. In Javascript, the mantissa is 53 bits, and the exponent is 11 bits.

When you see numbers expressed as, for example, 3.5346367e+22, the mantissa is 3.5246367, and the exponent is 22.

The numbers you are trying to store are larger than the maximum value of the mantissa, so your numbers get rounded, and larger numbers get an exponent.

Long story short, unless you're doing arithmetic operations with these huge numbers, you should store them as a string.

Lastly, you should expressed JSON Arrays as actual JSON Arrays, and not as objects that pretend to be arrays by defining integer keys and a length property:

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

// Not this
json = '{0:"16970861903381446063", length:1}';
Triptych
Thanks for the confirmation. FP is evil.
Steven Sudit