2013-06-26 17 views
25

Widziałem jedną z najdziwniejszych rzeczy w javascript. boczne serwer (sprężyna)JavaScript long integer

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

wrócić pojedynczy długi wartości i:

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

Reprezentuje długiej całkowitą, „793548328091516900” zastępując (zaokrąglenia rzeczywiście) dwie ostatnie cyfry z 0s . Kiedy wysyłam żądanie GET z paska adresu przeglądarki, numer ten jest poprawny; w związku z tym jest to kwestia js, moim zdaniem.

Wracając ciąg zamiast długo z serwera i przenoszenia go z:

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

oczywiście rozwiązanie. Ale nie mam tyle szczęścia, że ​​muszę obsłużyć złożone POJO (przekonwertowane na JSON), którego niektóre pola (niektóre są zagnieżdżone) są wpisane z typem java.lang.Long. Jeśli spróbuję rzucić to POJO do innego obiektu, nie ma pól wpisanych na Long, jest to oczywiście uciążliwe.

Czy istnieje jakieś rozwiązanie tej przeszkody w jaśniejszy sposób?

Odpowiedz

45

W Javie masz 64 bity liczb całkowitych i właśnie tego używasz.

W JavaScript wszystkie liczby to 64 bits floating point numbers. Oznacza to, że nie możesz reprezentować w JavaScript wszystkich longów Java. Rozmiar mantysy wynosi około 53 bitów, co oznacza, że ​​twój numer, 793548328091516928, nie może być dokładnie przedstawiony jako numer JavaScript.

Jeśli naprawdę potrzebujesz do czynienia z takimi liczbami, musisz reprezentować je w inny sposób. Może to być ciąg znaków lub określona reprezentacja, taka jak tablica cyfr. Niektóre biblioteki "dużych liczb" są dostępne w JavaScript.

+0

oznacza, że ​​nie ma rozwiązania? – px5x2

+6

@ px5x2 brak rozwiązania opartego na "liczbie javascript". Najlepsze rozwiązanie twojego problemu zależy od dokładnych wymagań. Jeśli chcesz je wyświetlić, wyślij je jako ciągi. –

+0

@dystroy: zły pomysł ze względu na strefy czasowe –

4

Może się spóźnić, ale zdecydowanie pomaga innym osobom, które pierwszy raz to robią.

Ja też chciałem obliczenia dużych liczb w JavaScript. Istnieje wiele bibliotek dostępnych do obsługi takich numerów. Ale większość z nich może marnować dużo czasu. Tutaj, https://github.com/peterolson/BigInteger.js, jest bezpośrednim, kompletnym (dla środowiska bez węzłów i środowisk węzła JS) i działającym rozwiązaniem dla wszystkich operacji na dostępnych dużych liczbach. lub znaleźć następujący prosty i przykładowy działający fragment kodu HTML, który oblicza modulo/reszta,

<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>