2013-06-26 9 views
25

Tôi đã thấy một trong những điều kỳ lạ nhất trong javascript. Phía máy chủ (mùa xuân):Số nguyên dài Javascript

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

Tôi trả về một giá trị lâu đơn và:

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

Nó đại diện cho số nguyên dài như "793548328091516900" thay thế (làm tròn thực sự) hai chữ số cuối cùng với 0s . Khi tôi thực hiện yêu cầu GET đó từ thanh địa chỉ của bất kỳ trình duyệt nào, số được biểu thị chính xác; do đó, đây là một vấn đề js, theo ý kiến ​​của tôi.

Trả về một chuỗi thay vì dài từ máy chủ và xử lý nó với:

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

rõ ràng là một giải pháp. Nhưng tôi không may mắn như vậy, tôi phải xử lý một POJO phức tạp (chuyển đổi thành JSON) mà một số trường (một số được lồng nhau) được gõ với loại java.lang.Long. Nếu tôi cố gắng cast POJO này đến một đối tượng khác không có trường được gõ Long, thì rõ ràng là cồng kềnh.

Có giải pháp nào cho trở ngại đó theo cách rõ ràng hơn không?

Trả lời

45

Trong Java, bạn có số nguyên 64 bit và đó là những gì bạn đang sử dụng.

Trong JavaScript, tất cả các số là 64 bits floating point numbers. Điều này có nghĩa là bạn không thể đại diện trong JavaScript tất cả các lần kéo dài Java. Kích thước của mantissa là khoảng 53 bit, có nghĩa là số của bạn, 793548328091516928, không thể được biểu diễn chính xác như một số JavaScript.

Nếu bạn thực sự cần xử lý các con số như vậy, bạn phải trình bày chúng theo một cách khác. Đây có thể là một chuỗi, hoặc một biểu diễn cụ thể như một mảng chữ số. Một số thư viện "số lớn" có sẵn trong JavaScript.

+0

có nghĩa là không có giải pháp? – px5x2

+6

@ px5x2 không có giải pháp dựa trên "số javascript". Giải pháp tốt nhất cho vấn đề của bạn sẽ phụ thuộc vào các yêu cầu chính xác. Nếu bạn chỉ muốn hiển thị chúng, hãy gửi chúng dưới dạng chuỗi. –

+0

@dystroy: ý tưởng tồi vì múi giờ –

4

Có thể đến trễ, nhưng chắc chắn sẽ giúp những người khác điều hành tình huống này lần đầu tiên.

Tôi cũng muốn một số phép tính với số lượng lớn bằng JavaScript. Có rất nhiều thư viện có sẵn để xử lý các con số như vậy. Nhưng hầu hết trong số họ có thể lãng phí rất nhiều thời gian của bạn. Ở đây, https://github.com/peterolson/BigInteger.js, là một trực tiếp, hoàn chỉnh (đối với môi trường không phải nút và môi trường JS nút), và giải pháp làm việc cho tất cả các hoạt động trên số lượng lớn có sẵn. hoặc tìm đoạn mã HTML hoạt động đơn giản và mẫu sau đây để tính toán modulo/remainder,

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