Các loại dấu chấm động kích thước cố định


90

Trong stdint.h(C99), boost / cstdint.hppcstdint (C ++ 0x), có loại int32_t.

Có các loại dấu phẩy động có kích thước cố định tương tự không? Một cái gì đó như thế float32_tnào?


4
Tại sao bạn cần một cái gì đó như vậy?
AraK

39
Bạn cần một thứ như vậy khi bạn có cấu trúc dữ liệu với giá trị dấu phẩy động và bạn cũng muốn biết chính xác kích thước của nó.
mob

5
@mobrule: Nếu bạn chỉ cần biết kích thước là bao nhiêu, bạn sử dụng sizeoftoán tử. Loại như thế này sẽ hữu ích khi một thuật toán yêu cầu nó phải có kích thước cụ thể đã biết.
Stephen Canon

6
@Stephen Canon - vâng, khi bạn muốn đảm bảo kích thước là bao nhiêu. Giả sử, một phiên bản cấu trúc dữ liệu của bạn sẽ vừa với 64 bit và có thể được chuyển theo giá trị đến một số thư viện bên ngoài.
mob

5
@StephenCanon Hãy xem xét một thư viện tuần tự hóa đa nền tảng. Làm thế nào có thể sizeofđược sử dụng để giải quyết vấn đề của các loại thả nổi và không quản lý nhất quán?
Kyle Strand

Câu trả lời:


47

Không có gì như thế này tồn tại trong các tiêu chuẩn C hoặc C ++ hiện tại. Trên thực tế, thậm chí không có gì đảm bảo rằng đó floatsẽ là một định dạng dấu phẩy động nhị phân.

Một số trình biên dịch đảm bảo rằng floatkiểu sẽ là định dạng nhị phân 32 bit IEEE-754. Một số không. Trên thực tế, thực tế floatlà loại IEEE-754 singletrên hầu hết các các nền tảng không nhúng, mặc dù áp dụng các cảnh báo thông thường về một số trình biên dịch đánh giá biểu thức ở định dạng rộng hơn.

Có một nhóm làm việc thảo luận về việc bổ sung các ràng buộc ngôn ngữ C cho bản sửa đổi năm 2008 của IEEE-754, nhóm có thể xem xét đề xuất rằng nên thêm một typedef như vậy. Nếu điều này được thêm vào C, tôi hy vọng tiêu chuẩn C ++ sẽ tuân theo ... cuối cùng.


3
Bất kể IEEE-754 hay không, nó vẫn sẽ không ngăn chặn các vấn đề về tính di động của thiết bị cuối.
Mark B

1
@Pietro: việc thay đổi ngôn ngữ sẽ không ảnh hưởng đến khả năng tương thích phần cứng của bạn, nó chỉ ngăn một số phần cứng tuân thủ. Bảo đảm IEEE FP sẽ giúp ích gì cho tính di động?
Potatoswatter

1
@Potatoswatter: Nó sẽ khuyến khích các nhà cung cấp phần cứng cung cấp các giải pháp tuân thủ. Nếu phần a hỗ trợ tiêu chuẩn C mà không cần hack thư viện soft-float và phần b thì không, đó là một lợi thế thị trường cho phần a.
Stephen Canon

2
@Potatoswatter: (Hầu như) không ai quan tâm đến tốc độ của phần cứng. Chúng tôi quan tâm đến tốc độ của phần mềm chạy trên phần cứng. Phần mềm có thể nhanh hơn nếu phần cứng mà nó đang chạy được tuân theo các tiêu chuẩn và phần mềm không cần phát hiện và vá 15 trường hợp đặc biệt khác nhau tùy thuộc vào nền tảng mà nó đang chạy.
Stephen Canon

8
Làm thế nào trên Earth bạn sẽ có được tính di động tốt hơn bằng cách ngăn mã của bạn biên dịch trên một số kiến ​​trúc thích hợp? Hoặc bạn dựa vào phao nổi là IEEE, trong trường hợp này mã của bạn sẽ đã chạy trên mọi thực hiện IEEE-tuân thủ và không có gì khác, hoặc bạn không, trong trường hợp này mã của bạn sẽ chạy trên một phạm vi rộng lớn hơn của hệ thống. Nếu C ++ đảm bảo IEEE tuân thủ, mã của bạn sẽ không có được một cách kỳ diệu di động hơn, bạn chỉ muốn loại trừ rằng nó có thể bao giờ chạy trên những kiến trúc không tuân thủ. Logic của bạn là hoàn toàn ngược.
jalf

29

Nếu bạn muốn biết liệu của bạn có phải floatlà loại IEEE 32-bit hay không, hãy kiểm tra std::numeric_limits<float>::is_iec559. Đó là một hằng số thời gian biên dịch, không phải là một hàm.

Nếu bạn muốn chống đạn tốt hơn, hãy kiểm tra std::numeric_limits<float>::digitsđể đảm bảo rằng chúng không lén lút sử dụng độ chính xác kép tiêu chuẩn IEEE cho float. Nó phải là 24.

Khi nói đến long double, điều quan trọng hơn là phải kiểm tra digitsvì có một số định dạng IEEE mà nó có thể là hợp lý: 128 bit (chữ số = 113) hoặc 80 bit (chữ số = 64).

Sẽ không thực tế nếu có float32_tnhư vậy vì bạn thường muốn sử dụng phần cứng dấu phẩy động, nếu có và không phải quay lại triển khai phần mềm.


Các long doubleđịnh dạng trên OS X (cả 32-bit và 64-bit Intel) là chính xác IEEE-754 đôi định dạng mở rộng lưu trữ theo thứ tự về cuối nhỏ. Không có gì thú vị về nó cả. Các byte 0-7 giữ trường nghĩa và các byte 8 và 9 giữ trường số mũ và dấu.
Stephen Canon

@Stephen: đó là tin tốt: v). Điều đó có đồng ý với những con số tôi đã đăng không?
Potatoswatter

1
Hãy nhớ rằng mở rộng kép (không giống như các định dạng 754 khác) có một bit có ý nghĩa và dẫn đầu rõ ràng, vì vậy 5.0Lcũng có một ý nghĩa a000000000000000. Số mũ không chệch của nó là +2 và độ lệch của số mũ mở rộng gấp đôi là 3fff, do đó số mũ chệch cho 5.0L là 4001. Mẫu byte thực tế khi được lưu trữ theo thứ tự little-endian là 00 00 00 00 00 00 00 a0 01 40, và nếu bạn xem đó là hai số nguyên 64 bit nhỏ, bạn sẽ thấy chính xác những gì bạn đã quan sát.
Stephen Canon

(*) được mở rộng gấp đôi do Intel triển khai trong phần cứng, nghĩa là. Định dạng mở rộng kép không thực sự được ghim lại như hai định dạng cơ bản khác của IEEE-754 (1985).
Stephen Canon

@Stephen: Tôi khá chắc chắn rằng 4001trong little-endian là 01 40 00 00 ...Nếu không có gì khác, byte ít quan trọng nhất sẽ xuất hiện trước. Tôi hy vọng chuỗi a0 01 40sẽ xuất hiện ở đâu đó trong số (nếu chúng chỉ thực hiện một vòng quay) nhưng tôi không nghĩ rằng bạn đã giải thích tại sao a001 40nằm trong các nửa hoàn toàn riêng biệt.
Potatoswatter

18

Nếu bạn nghĩ rằng việc có các typedef như float32_t và float64_t là không thực tế vì bất kỳ lý do gì, thì bạn hẳn đã quá quen thuộc với hệ điều hành quen thuộc của mình, trình biên dịch và bạn không thể nhìn ra ngoài tổ ấm nhỏ của mình.

Có những phần cứng nguyên bản chạy các hoạt động dấu chấm động IEEE 32 bit và những phần cứng khác chạy 64 bit. Đôi khi các hệ thống như vậy thậm chí phải nói chuyện với nhau, trong trường hợp đó, điều cực kỳ quan trọng là phải biết liệu bộ đôi là 32 bit hay 64 bit trên mỗi nền tảng. Nếu nền tảng 32-bit phải thực hiện các tính toán quá mức dựa trên các giá trị 64-bit từ nền tảng khác, chúng tôi có thể muốn truyền xuống độ chính xác thấp hơn tùy thuộc vào yêu cầu về thời gian và tốc độ.

Cá nhân tôi cảm thấy không thoải mái khi sử dụng phao và nhân đôi trừ khi tôi biết chính xác chúng có bao nhiêu bit trên Platfrom của tôi. Thậm chí nhiều hơn thế nếu tôi muốn chuyển những thứ này sang một nền tảng khác qua một số kênh liên lạc.


"Cá nhân tôi cảm thấy không thoải mái khi sử dụng float và double trừ khi tôi biết chính xác chúng có bao nhiêu bit trên Platfrom của tôi. Thậm chí nhiều hơn thế nếu tôi chuyển chúng sang một nền tảng khác qua một số kênh liên lạc." - Ý bạn là bạn sử dụng các định dạng tệp văn bản? Với những thứ này, có nhược điểm là kích thước tệp: một float 32 cần 4 byte; những ở dạng văn bản có thể đại diện cho một số có bốn chữ số chỉ ...
Pietro

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.