2010-03-19 35 views
5

Tôi cần đại diện cho số điểm nổi kép kép (75 bit) IEEE 754-1985 ở dạng văn bản có thể đọc được bằng con người, với điều kiện biểu mẫu văn bản có thể được phân tích ngược lại chính xác cùng một số (bit-khôn ngoan).Biểu diễn văn bản chính xác của IEEE "đôi"

Điều này có thể thực hiện/thực tế để thực hiện mà không cần in các byte thô không? Nếu có, mã để làm điều này sẽ được nhiều đánh giá cao.

+1

Vấn đề ngôn ngữ. Bạn đang làm việc ở ngôn ngữ nào Không thể cung cấp mã không có ngôn ngữ cụ thể được đề cập trong vấn đề. –

+0

Tôi đã không đề cập đến ngôn ngữ (D) vì nó tương đối hiếm, vì vậy tôi đã lên kế hoạch viết lại một thuật toán được viết bằng bất kỳ ngôn ngữ nào để D. –

+0

Làm thế nào về NaN, -0.0, inf, -inf? Câu trả lời hiện tại dường như không tính đến điều này. –

Trả lời

11

Lựa chọn tốt nhất: Sử dụng định dạng C99 thập lục phân dấu chấm động:

printf("%a", someDouble); 

Strings sản xuất theo cách này có thể được chuyển đổi trở lại thành double với C99 strtod() chức năng, và cũng với scanf() chức năng. Một số ngôn ngữ khác cũng hỗ trợ định dạng này. Một số ví dụ:

decimal number %a format  meaning 
-------------------------------------------- 
2.0    0x1.0p1  1.0 * 2^1 
0.75    0x1.8p-1  1.5 * 2^-1 

Định dạng thập lục phân có ưu điểm là tất cả các cơ quan đại diện là chính xác. Do đó, việc chuyển đổi chuỗi trở lại thành dấu phẩy động sẽ luôn cung cấp số nguyên gốc, ngay cả khi ai đó thay đổi chế độ làm tròn mà trong đó chuyển đổi được thực hiện. Điều này không đúng đối với các định dạng không chính xác.

Nếu bạn không muốn sử dụng định dạng thập lục phân vì bất kỳ lý do gì và sẵn sàng giả định rằng chế độ làm tròn sẽ luôn tròn thành gần nhất (mặc định), thì bạn có thể lấy đi định dạng dữ liệu của mình dưới dạng số thập phân với ít nhất 17 chữ số có nghĩa. Nếu bạn có một thói quen chuyển đổi được làm tròn chính xác (hầu hết - không phải tất cả - nền tảng nào), điều này sẽ đảm bảo rằng bạn có thể thực hiện một chuyến đi khứ hồi từ chuỗi kép và ngược lại mà không mất đi độ chính xác nào.

+0

Cảm ơn bạn đã trả lời rất chi tiết! –

1

Có, nó có thể được thực hiện, mặc dù việc triển khai phụ thuộc vào ngôn ngữ. Ý tưởng cơ bản chỉ đơn giản là in nó ra với độ chính xác đầy đủ.

Lưu ý rằng ngược lại là không đúng mặc dù: một số số có thể được biểu diễn chính xác theo dạng thập phân đơn giản không thể được biểu diễn dưới dạng nhị phân.

2

.NET Framework có một định dạng khứ hồi cho điều này:

string formatted = myDouble.ToString("r"); 

Từ các tài liệu:

Các khứ hồi specifier đảm bảo rằng một giá trị số chuyển thành một chuỗi sẽ được phân tích cú pháp lại thành cùng một giá trị số . Khi giá trị bằng số là được định dạng bằng cách sử dụng thông số này, nó là được thử nghiệm đầu tiên theo định dạng chung, với 15 khoảng trống chính xác cho Đôi và 7 không gian chính xác cho Đơn. Nếu giá trị thành công được phân tích cú pháp trở lại cùng một giá trị số, , giá trị được định dạng bằng cách sử dụng thông số chung định dạng . Tuy nhiên, nếu giá trị không được phân tích cú pháp thành công thành giá trị bằng nhau, thì giá trị được định dạng bằng 17 chữ số của chính xác cho một số và 9 chữ số là chính xác cho một đơn.

Phương pháp này tất nhiên có thể được tạo lại bằng hầu hết mọi ngôn ngữ.

5

Sound như bạn muốn Burger's algorithm (PDF):

Trong chế độ tự do định dạng các thuật toán tạo ra chuỗi sản lượng một cách chính xác tròn ngắn nhất có thể chuyển đổi để số tương tự khi đọc lại trong bất kể như thế nào người đọc phá vỡ quan hệ khi làm tròn.

Sample source code (trong C và sơ đồ) cũng khả dụng.

Đây là thuật toán được sử dụng trong Python 3.x để đảm bảo float s có thể được chuyển đổi thành chuỗi và quay lại mà không bị mất chính xác. Trong Python 2.x, float s luôn thể hiện với 17 chữ số có nghĩa vì:

repr(float) sản xuất 17 chữ số có nghĩa vì nó chỉ ra rằng đủ (trên hầu hết các máy) để eval(repr(x)) == x chính xác cho tất cả các phao nổi hữu hạn x, nhưng làm tròn đến 16 chữ số là không đủ để làm cho điều đó đúng. (Nguồn: http://docs.python.org/tutorial/floatingpoint.html)

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