2013-06-26 32 views
25

Ho visto una delle cose più strane in javascript. Il lato server (molla):Numero intero Javascript

@RequestMapping(value = "/foo", method = RequestMethod.GET) 
    @ResponseBody 
    public Long foo() { 
     return 793548328091516928L; 
    } 

torno un singolo valore lunga e:

$.get('/foo').done(function(data){ 
    console.log(data); 
}); 

Esso rappresenta il tempo intero come "793.548.328.091,5169 milioni" sostituzione (arrotondamento in effetti) le ultime due cifre con 0s . Quando effettuo la richiesta GET da qualsiasi barra degli indirizzi del browser, il numero è rappresentato correttamente; quindi questa è una questione js, secondo me.

Tornando stringa anziché lungo dal server e trattare con:

var x = new Number(data).toFixed(); 

ovviamente una soluzione. Ma non sono così fortunato che, devo gestire un POJO complesso (convertito in JSON) i cui campi (alcuni sono nidificati) sono digitati con il tipo java.lang.Long. Se provo a lanciare questo POJO su un altro oggetto non avendo campi digitati a lungo, è ovviamente ingombrante.

C'è qualche soluzione a quell'ostacolo in modo più chiaro?

risposta

45

In Java, hai 64 bit interi, ed è quello che stai usando.

In JavaScript, tutti i numeri sono 64 bits floating point numbers. Ciò significa che non è possibile rappresentare in JavaScript tutti i long Java. La dimensione della mantissa è di circa 53 bit, il che significa che il tuo numero, 793548328091516928, non può essere rappresentato esattamente come un numero JavaScript.

Se davvero hai bisogno di trattare tali numeri, devi rappresentarli in un altro modo. Questa potrebbe essere una stringa o una rappresentazione specifica come un array di cifre. Alcune librerie "grandi numeri" sono disponibili in JavaScript.

+0

significa che nessuna soluzione? – px5x2

+6

@ px5x2 nessuna soluzione basata su "numero javascript". La migliore soluzione al tuo problema dipenderà dai requisiti esatti. Se si desidera solo visualizzarli, inviarli come stringhe. –

+0

@dystroy: una cattiva idea a causa dei fusi orari –

4

Potrebbe essere in ritardo, ma sicuramente aiuta gli altri che gestiscono questa situazione per la prima volta.

Anch'io volevo qualche calcolo su grandi numeri in JavaScript. Ci sono molte librerie disponibili per trattare tali numeri. Ma la maggior parte di loro potrebbe sprecare molto del tuo tempo. Qui, https://github.com/peterolson/BigInteger.js, è diretto, completo (per ambienti non nodo e ambienti nodo JS) e soluzione operativa per tutte le operazioni su grandi numeri disponibili. o trovare il seguente frammento di codice semplice e campione HTML operativo che calcola modulo/resto,

<script src="http://peterolson.github.com/BigInteger.js/BigInteger.min.js"></script> 
<script type="text/javascript"> 
    function modTest(){ 
     var rem = bigInt("1738141852226360940").mod("32").valueOf(); 
     console.log(rem); 
     document.getElementById("remainder").innerHTML = rem; 
    } 
</script> 

<BODY onload="modTest();"> 
    <p id="remainder"></p> 
</BODY>