How to read 8-byte floating point numbers from binary?use fread

fseek(fid,56,'bof');
x = fread(fid,1,'float64','b')

3 Comments

What is or isn't happening? Why do you think this code is incorrect?
This is correct, but a new question has arisen. For example, how can "DC 88 12 C0 C1 4F 7C A9" be replaced with "C0 12 88 DC A9 7C 4F C1"? Then read as double-precision floating point
When you fopen you should specify the byte order as the third parameter to fopen, unless you are reading from something with mixed orders.
If you are reading from something with mixed orders but know the order for one particular binary fread then specify the byte order as a parameter to fread.
If you are reading a sequence of bytes at one time and regrouping them (such as if you were reading a structure with mixed datatype) then if necessary use swapbytes after any necessary typecast()

Sign in to comment.

 Accepted Answer

With 'ieee-le' format the bytes are read in the order [8,7,6,5,4,3,2,1], with 'ieee-be' as [1,2,3,4,5,6,7,8]. There is no format to store doubles with the byte order [4,3,2,1,8,7,6,5]. Yo you have to convert the order manually by reading the bytes, mix them as wanted and use typecast for the conversion.
[EDITED] As code:
bytes = fread(fid, 8, '*uint8');
bytes = bytes([4,3,2,1,8,7,6,5]);
value = typecast(bytes, 'double')

8 Comments

Yes, but how to implement the 8-byte big-endian conversion in matlab?
If the data is in big-endian then either specify ieee-be or swapbytes()
format long g
T = -pi
T =
-3.14159265358979
fprintf('source data\n');
source data
t64 = typecast(T, 'uint64');
fprintf('%016x\n', t64(1));
c00921fb54442d18
t8 = typecast(T, 'uint8');
fprintf('%02x ', t8(1:8)); fprintf('\n');
18 2d 44 54 fb 21 09 c0
fn = tempname;
fid = fopen(fn, 'w', 'ieee-be');
fwrite(fid, T, 'double');
fclose(fid);
fprintf('reading from file\n');
reading from file
dinfo = dir(fn);
fprintf('file is %d bytes long\n', dinfo.bytes);
file is 8 bytes long
fid = fopen(fn, 'r');
in_bytes = fread(fid, [1 inf], '*uint8');
fprintf('%02x ', in_bytes); fprintf('\n');
c0 09 21 fb 54 44 2d 18
frewind(fid)
in_64 = fread(fid, [1 inf], '*double');
in_64
in_64 =
3.20737563067642e-192
swapbytes(in_64)
ans =
-3.14159265358979
fprintf('%016x\n', typecast(in_64, 'uint64'));
182d4454fb2109c0
frewind(fid)
in_64 = fread(fid, [1 inf], '*double', 'ieee-be');
in_64
in_64 =
-3.14159265358979
swapbytes(in_64)
ans =
3.20737563067642e-192
fprintf('%016x\n', typecast(in_64, 'uint64'));
c00921fb54442d18
fclose(fid);
Thank you for your answer. Sorry to reply you so late, my question now is how to turn 1 2 3 4 5 6 7 8 into 5 6 7 8 1 2 3 4?
typecast to uint32, exchange pairs of entries, typecast back to double .
format long g
in_64 = 0x0102030405060708
in_64 = uint64
72623859790382856
d64 = typecast(in_64, 'double')
d64 =
8.20788039913184e-304
num2hex(d64)
ans = '0102030405060708'
temp_in = typecast(d64, 'uint32');
temp_out = temp_in([2:2:end; 1:2:end]);
d64swap = typecast(temp_out, 'double')
d64swap =
1.85164890819352e-284
num2hex(d64swap)
ans = '0506070801020304'
bytes = fread(fid, 8, '*uint8');
bytes = bytes([5,6,7,8,1,2,3,4]);
value = typecast(bytes, 'double')
The picture is my hexadecimal file, the shaded part is 8 bytes as a parameter, my original code is as follows:
fseek(fid,56,'bof');
x = fread(fid,1,'float64','b');
The output result is -8.041e27, which is obviously wrong and should be of the order of e6;
Now we need to convert between big and little endian, C5 B9 FB 60 C1 4B FD CA convert to
C1 4B FD CA C5 B9 FB 60(it should be this),and then read as a double-precision floating-point number.
Thank you very much for your answer and look forward to your reply.
As I have suggested already, except for the changed byte order:
% fseek(fid, 56, 'bof');
% bytes = fread(fid, 8, '*uint8');
% Manually:
bytes = uint8(sscanf('C5 B9 FB 60 C1 4B FD CA', '%x')).';
value = typecast(fliplr(bytes), 'double') % As your fread('float64')
value = -8.0410e+27
% [197, 185, 251, 96, 193, 75, 253, 202]
bytes = bytes([4,3,2,1,8,7,6,5]);
value = typecast(bytes, 'double')
value = -3.6689e+06
Now the byte order and the order of 4-Byte-blocks is swapped.
Thank you very much for solving the problem that caused me a lot of headaches.

Sign in to comment.

More Answers (0)

Categories

Asked:

on 28 Oct 2021

Edited:

Jan
on 12 Nov 2021

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!