2009-03-10 16 views
5

Chương trình C sẽ tách các cặp đôi liên tiếp thành một tệp nhị phân. Tôi muốn đọc chúng vào Python. Tôi đã cố gắng sử dụng struct.unpack('d',f.read(8))Phương pháp nào tốt nhất để đọc gấp đôi từ tệp nhị phân được tạo trong C?

EDIT: tôi đã sử dụng sau trong C để viết một số đôi ngẫu nhiên

r = drand48(); 
fwrite((void*)&r, sizeof(double), 1, data); 

Các lỗi đã được sửa nhưng tôi không thể đọc được giá trị đầu tiên. cho một số 0.000 .. tất cả nó đọc nó như 3.90798504668055 nhưng phần còn lại là tốt.

+0

Nó có thể được kết nối với độ trễ không chính xác (những gì đến trước byte ít quan trọng nhất hay không). Hiển thị những byte nào bạn đang cố đọc. – jfs

+0

Tôi xin lỗi. Tôi gần như đã khắc phục vấn đề nên tôi đánh dấu nó là đã trả lời. Tôi muốn xem số đầu tiên được đọc đúng. – gnosio

+0

Bạn có thể cung cấp kết xuất 40 byte đầu tiên của tệp cùng với mã bạn hiện đang sử dụng để đọc không? –

Trả lời

3

Tôi nghĩ rằng bạn đang thực sự đọc số một cách chính xác, nhưng đang nhận được nhầm lẫn bởi màn hình. Khi tôi đọc số từ tập tin được cung cấp của bạn, tôi nhận được "3.907985046680551e-14" - đây là gần như nhưng không hoàn toàn bằng không (0.000000000000039 ở dạng mở rộng). Tôi nghi ngờ mã C của bạn chỉ là in nó với độ chính xác thấp hơn python.

[Chỉnh sửa] Tôi vừa thử đọc tệp trong C và tôi nhận được kết quả tương tự (mặc dù hơi kém chính xác: 3.90799e-14) (sử dụng printf ("% g", val)), vì vậy tôi nghĩ rằng nếu giá trị này là không chính xác, nó xảy ra ở phía bên viết, thay vì đọc.

+0

Hey Brian, bạn đóng đinh nó. Tôi đã được lười biếng để mở rộng nó :(. Độ chính xác là lý do cho 2 giá trị khác nhau.Cảm ơn sự giúp đỡ. – gnosio

1

Bạn có thể giải thích về "không hoạt động" không? Lệnh có bị hỏng không? Dữ liệu có bị lỗi không? Điều gì đã xảy ra?

Nếu lệnh hỏng:

  • Hãy chia sẻ sản lượng lỗi của lệnh

Nếu dữ liệu chỉ đơn giản là bước ra sai:

  • Làm hệ thống tạo và đọc dữ liệu có cùng một endianness? Nếu một người là người lớn tuổi, và người kia là người ít tuổi, thì bạn cần phải chỉ định một chuyển đổi cuối cùng trong chuỗi định dạng của bạn.

  • Nếu độ tin cậy của hai máy tính giống nhau, dữ liệu được ghi vào tệp như thế nào, chính xác là? Bạn có biết? Nếu bạn làm như vậy, thì giá trị được ghi vào tệp là gì và giá trị không chính xác bạn đã nhận được là bao nhiêu?

0
  • f.read(8) có thể quay trở lại ít hơn 8 byte
  • dữ liệu có thể có sự liên kết và/hoặc endianness khác nhau:

    >>> for c in '@=<>': 
    ...  print repr(struct.pack(c+'d', -1.05)) 
    ... 
    '\xcd\xcc\xcc\xcc\xcc\xcc\xf0\xbf' 
    '\xcd\xcc\xcc\xcc\xcc\xcc\xf0\xbf' 
    '\xcd\xcc\xcc\xcc\xcc\xcc\xf0\xbf' 
    '\xbf\xf0\xcc\xcc\xcc\xcc\xcc\xcd' 
    >>> struct.unpack('<d', '\xbf\xf0\xcc\xcc\xcc\xcc\xcc\xcd') 
    (-6.0659880001157799e+066,) 
    >>> struct.unpack('>d', '\xbf\xf0\xcc\xcc\xcc\xcc\xcc\xcd') 
    (-1.05,) 
    
0

Các tốt nhất phương pháp sẽ được sử dụng một Tệp văn bản ASCII:

0,0
3,1416
3,90798504668055

ở chỗ nó sẽ là di động và làm việc với bất kỳ loại nổi thực hiện điểm ở một mức độ.

Đọc dữ liệu nhị phân thô từ địa chỉ bộ nhớ của double không thể di chuyển được và bị ràng buộc thất bại trong một số triển khai khác.

Tất nhiên, bạn có thể sử dụng định dạng nhị phân cho gọn nhẹ, nhưng chức năng C di động viết ở định dạng đó sẽ không giống như đoạn mã của bạn.

Ít nhất, mã phải được bao quanh bởi một chuỗi ifs/ifdefs kiểm tra xem biểu diễn bộ nhớ của double s được máy hiện tại sử dụng có khớp chính xác với trình thông dịch Python hay không.

Viết mã như vậy sẽ rất khó, đó là lý do tại sao tôi đề xuất giải pháp văn bản ASCII dễ, sạch, di động và dễ đọc.

Điều này sẽ là định nghĩa "tốt nhất" của tôi là.

+0

Hi Aib, tôi muốn tôi có thể làm điều đó nhưng một bãi chứa bộ nhớ của nó và tôi không có kiểm soát cách xuất của nó. Tôi có thành công tốt với giải nén nhưng vì một lý do nào đó không đọc chính xác Double đầu tiên. – gnosio

+0

Tôi đoán điều đó, nhưng vẫn muốn làm cho quan điểm của tôi cho độc giả trong tương lai. Tôi rất vui vì bạn đã giải quyết được vấn đề của mình. – aib

1

Trước tiên, bạn đã thử pickle chưa? Không ai đã cho thấy bất kỳ mã Python chưa ... Dưới đây là một số mã để đọc trong nhị phân trong python:

import Numeric as N 
import array 
filename = "tmp.bin" 
file = open(filename, mode='rb') 
binvalues = array.array('f') 
binvalues.read(file, num_lon * num_lat) 
data = N.array(binvalues, typecode=N.Float) 

file.close() 

Trường hợp f ở đây quy định chính xác đơn, 4-byte nổi, con số. Tìm bất kỳ kích thước dữ liệu của bạn là cho mỗi mục nhập và sử dụng đó.

Đối với dữ liệu nhị phân không bạn có thể làm một cái gì đó đơn giản như thế này:

tmp=[] 
    for line in open("data.dat"): 
       tmp.append(float(line)) 
+0

Hey Alex, tôi đã thử dưa nhưng đối với vấn đề của tôi tôi không được bảo đảm của tất cả các giá trị được tăng gấp đôi. Chúng có thể là Ints, float hoặc Doubles. Tất cả những gì tôi biết là vị trí và loại giá trị cần đọc. Cảm ơn sự giúp đỡ mặc dù :) – gnosio

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