2016-02-29 12 views
12

Một số API, chẳng hạn như paypal API sử dụng loại chuỗi trong JSON để biểu thị số thập phân. Vì vậy, "7.47" thay vì 7.47.Tại sao bạn sử dụng một chuỗi trong JSON để biểu thị số thập phân

Tại sao/khi nào thì đây có thể là ý tưởng hay khi sử dụng loại giá trị số json? AFAIK loại giá trị số cho phép độ chính xác vô hạn cũng như ký pháp khoa học.

+2

vì việc sử dụng phao cho tiền tệ sẽ chỉ gây ra lỗi trên đường. float không được sử dụng để đại diện cho các giá trị thế giới thực như tiền - không đáng tin cậy, anyways. ví dụ. 7,47 thực sự có thể là 7.4699999923423423423 khi chuyển thành phao. một hệ thống đơn giản chỉ đơn giản là cắt bớt các chữ số phụ ngoài sẽ dẫn đến 7,46 và bây giờ bạn đã mất một xu ở đâu đó ... sắc thái của Superman II (I?). –

+2

@MarcB Tôi quen thuộc với lý do tại sao bạn sẽ không sử dụng một phao cho tiền tệ, nhưng là số JSON thực sự là một phao? Theo tôi hiểu đó là một số độc lập về ngôn ngữ và bạn có thể phân tích cú pháp một số JSON thẳng thành java 'BigDecmial' hoặc định dạng chính xác tùy ý khác bằng bất kỳ ngôn ngữ nào nếu nghiêng. – kag0

+0

phụ thuộc vào cách nó được trong hệ thống của paypal để bắt đầu với. json là ánh xạ 1: 1 giữa chuỗi văn bản nguyên khối và cấu trúc dữ liệu JS. nếu một "số" được lưu trữ dưới dạng một chuỗi '" ... "' trong chuỗi json, thì đó là một chuỗi trong cấu trúc dữ liệu gốc hoặc một thứ gì đó ánh xạ tới chuỗi. –

Trả lời

14

Lý do chính để chuyển các giá trị số trong JSON dưới dạng chuỗi là loại bỏ bất kỳ sự mất chính xác hoặc mơ hồ nào trong quá trình truyền.

Đúng là thông số JSON không chỉ định độ chính xác cho các giá trị số. Điều này không có nghĩa là các số JSON có độ chính xác vô hạn. Nó có nghĩa là độ chính xác số không được chỉ định, có nghĩa là việc triển khai JSON được tự do lựa chọn bất kỳ độ chính xác số nào thuận tiện cho việc triển khai hoặc mục tiêu của chúng. Đó là sự biến đổi này có thể là một nỗi đau nếu ứng dụng của bạn có các yêu cầu độ chính xác cụ thể.

Mất độ chính xác thường không rõ ràng trong mã hóa JSON của giá trị số (1.7 là đẹp và ngắn gọn) nhưng biểu thị trong phân tích cú pháp JSON và biểu diễn trung gian trên đầu nhận. Một hàm phân tích cú pháp JSON khá hợp lý sẽ phân tích cú pháp 1.7 thành một số dấu chấm động chính xác kép của IEEE. Tuy nhiên, độ dài hữu hạn/biểu diễn chính xác hữu hạn sẽ luôn chạy vào các số không thể được biểu diễn chính xác. Các số thủy lợi (như pi và e) không bao giờ có thể được biểu diễn chính xác trong một hệ hữu hạn. 1.7 có một biểu diễn hữu hạn theo ký hiệu thập phân (cơ sở 10), nhưng trong nhị phân (cơ sở 2) nó là một số vô tỉ - một chuỗi số vô hạn.

Vì vậy, hãy phân tích cú pháp 1.7 thành số dấu phẩy động trong bộ nhớ, sau đó in ra con số có khả năng sẽ trả về một cái gì đó như 1,69 - không 1,7. Người tiêu dùng có giá trị JSON 1.7 có thể sử dụng các kỹ thuật phức tạp hơn để phân tích và giữ lại giá trị trong bộ nhớ, chẳng hạn như sử dụng kiểu dữ liệu điểm cố định hoặc kiểu dữ liệu "chuỗi int" với độ chính xác tùy ý, nhưng điều này sẽ không hoàn toàn loại bỏ bóng ma mất độ chính xác trong chuyển đổi đối với một số số. Và thực tế là, rất ít trình phân tích cú pháp JSON bận tâm với các biện pháp cực đoan như vậy, vì lợi ích cho hầu hết các tình huống thấp và bộ nhớ và chi phí CPU cao. Vì vậy, nếu bạn muốn gửi một giá trị số chính xác cho người tiêu dùng và bạn không muốn chuyển đổi tự động giá trị thành biểu diễn số nội bộ điển hình, đặt cược tốt nhất của bạn là chuyển giá trị số ra dưới dạng chuỗi và cho người tiêu dùng biết chính xác chuỗi đó sẽ được xử lý như thế nào và khi nào các hoạt động số cần được thực hiện trên đó. Ví dụ: Trong một số nhà sản xuất JSON (JRuby, cho một), giá trị BigInteger tự động xuất ra JSON dưới dạng chuỗi, phần lớn vì phạm vi và độ chính xác của BigInteger lớn hơn nhiều so với độ chính xác kép của IEEE. Giảm giá trị BigInteger thành gấp đôi để xuất dưới dạng số JSON thường sẽ mất các chữ số có nghĩa.

Ngoài ra, thông số JSON (http://www.json.org/) nêu rõ rằng NaN và Infinities (INFs) không hợp lệ đối với các giá trị số JSON. Nếu bạn cần thể hiện các phần tử rìa này, bạn không thể sử dụng số JSON. Bạn phải sử dụng một chuỗi hoặc cấu trúc đối tượng.

Cuối cùng, có một khía cạnh khác có thể dẫn đến việc chọn gửi dữ liệu số dưới dạng chuỗi: kiểm soát định dạng hiển thị. Các số 0 và các số 0 ở đầu không đáng kể với giá trị số. Nếu bạn gửi giá trị số JSON 2.10 hoặc 004, sau khi chuyển đổi thành dạng số nội bộ, chúng sẽ được hiển thị dưới dạng 2.1 và 4.

Nếu bạn đang gửi dữ liệu sẽ được hiển thị trực tiếp cho người dùng, có thể bạn muốn số liệu tiền của mình xếp hàng độc đáo trên màn hình, căn chỉnh thập phân. Một cách để làm điều đó là làm cho khách hàng chịu trách nhiệm định dạng dữ liệu để hiển thị. Một cách khác để làm điều đó là để máy chủ định dạng dữ liệu để hiển thị. Đơn giản cho khách hàng để hiển thị các công cụ trên màn hình có lẽ, nhưng điều này có thể làm cho việc trích xuất các giá trị số từ chuỗi khó khăn nếu khách hàng cũng cần phải thực hiện tính toán trên các giá trị.

+0

Đừng đánh giá thấp tầm quan trọng của các số vô tỉ - có nhiều số vô tỉ hơn số hữu tỷ! Cả hai đều là những tập hợp vô hạn, nhưng đo lường của các sự vô lý lớn hơn thước đo của các lý trí. Hãy hỏi chuyên gia toán học địa phương của bạn. Mang cà phê. :> – dthorpe

+1

Bạn có thể cung cấp thêm một số ví dụ về khách hàng bị mất chính xác về mã hóa không? Ví dụ: Jackson trong Java sẽ chuyển đổi một cách hài hòa số thập phân json thành BigDecimal mà không làm mất bất kỳ độ chính xác nào. Thật khó chịu khi làm cho API của một người kém chính xác hơn (nó không phải là một chuỗi, nó là một số, mà json hỗ trợ) chỉ vì một số khách hàng chưa đặt tên đang làm những gì tôi sẽ coi là "điều sai" khi đưa ra một số json. –

0

tóm tắt Version

Chỉ cần trích dẫn từ câu trả lời @ dthorpe, như tôi nghĩ rằng đây là điểm quan trọng nhất:

Ngoài ra, spec JSON (http://www.json.org/) khẳng định một cách rõ ràng rằng Nans và infinities (INFs) không hợp lệ đối với các giá trị số JSON. Nếu bạn cần thể hiện các phần tử rìa này, bạn không thể sử dụng số JSON. Bạn phải sử dụng một chuỗi hoặc cấu trúc đối tượng.

Các vấn đề liên quan