2012-01-23 37 views
9

Tôi có một tệp có chứa [Double] được tuần tự hóa bởi Data.Binary mà tôi muốn đọc bằng C. Tức là, tôi muốn viết chương trình C đọc dữ liệu đó vào bộ nhớ là double[]. Tôi đang lập kế hoạch viết một chương trình Haskell để deserialize tệp dữ liệu và sau đó ghi dữ liệu nhị phân vào một tệp mới, đơn giản hơn mà tôi có thể đọc trực tiếp vào C, nhưng tôi không chắc cách viết ra dữ liệu nhị phân thô (ví dụ 8 byte cho một đôi).Ghi dữ liệu nhị phân với Haskell để đọc bằng C?

Trả lời

3

Sử dụng Data.Binary để tuần tự hóa Double hoặc Float giá trị không phải là điều tuyệt vời cho tính di động. Các trường hợp Binary tuần tự hóa các giá trị trong biểu mẫu thu được bằng decodeFloat, tức là một phần mềm và số mũ. Phần được xếp theo thứ tự là Integer. Phân tích cú pháp đó là bất tiện. Tốt hơn nhiều, như đã được đề xuất bởi ehird, đang sử dụng một biến thể tuần tự hóa chúng như là mẫu bit của đại diện IEEE-754, như được cung cấp bởi cereal-ieee754 - như ehird nhắc tôi, đã được hợp nhất (trừ một số chuyển đổi giữa dấu phẩy động và các loại từ) thành cereal - hoặc đã được đề cập data-binary-ieee754. Một tùy chọn khác là tuần tự hóa chúng dưới dạng chuỗi thông qua show. Điều đó có lợi thế là tránh bất kỳ vấn đề về tính cuối cùng nào.

+0

Nhân tiện, chức năng của cereal-ieee754 gần đây đã được hợp nhất thành ngũ cốc. – ehird

+0

Ah, cảm ơn. Tôi quên mất. Thật không may, các chuyển đổi 'Word64 <-> Double' và' Word32 <-> Float' đã bị loại bỏ, và chúng là những thứ duy nhất tôi muốn quan tâm trong một trong hai gói;) –

+0

Vâng, sẽ tốt hơn nếu chúng được tách ra thành một gói riêng biệt rằng các thư viện tuần tự hóa có thể phụ thuộc vào. – ehird

8

Bạn có thể sử dụng lại Data.Binary cho mục đích với gói data-binary-ieee754, cho phép tuần tự hóa Float s và Double s làm đại diện IEEE của chúng. Ví dụ:

import Data.List 
import Data.Binary.Put 
import Data.Binary.IEEE754 
import Control.Monad 

putRawDoubles :: [Double] -> Put 
putRawDoubles xs = do 
    putWord64le $ genericLength xs 
    mapM_ putFloat64le xs 

Nó sẽ được tốt đẹp nếu có một chất tương tự putWord64host cho Double s ở dữ liệu nhị phân-IEEE754, nhưng vì không có tôi chỉ đi với ít về cuối nhỏ. Nếu bạn muốn di chuyển qua các endianness mà không xử lý rõ ràng chuyển đổi trong chương trình C của mình, bạn có thể thử putWord64host . doubleToWord (doubleToWord cũng từ Data.Binary.IEEE754). Mặc dù tôi nghĩ rằng độ tin cậy số nguyên khác với tính điểm cuối nổi trên một số nền tảng ...

Ngẫu nhiên, tôi khuyên bạn nên sử dụng định dạng như vậy ngay cả đối với việc sắp xếp thường xuyên của bạn; IEEE nổi là phổ quát, và định dạng dấu phẩy động mặc định của nhị phân là lãng phí (như Daniel Fischer chỉ ra).

Bạn cũng có thể muốn xem xét thư viện tuần tự cereal, nhanh hơn nhị phân, duy trì tốt hơn (nhị phân chưa được cập nhật từ năm 2009) và hỗ trợ định dạng nổi IEEE built-in.

+1

Có hoặc là một số ít nền tảng có độ nổi và số nguyên khác nhau. Tôi quên mất. Nhưng những con thú này quá hiếm để lo lắng. –

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