Does fread use cast when reading non-integer byte data
4 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Dean Millard
le 6 Juin 2024
Modifié(e) : Dean Millard
le 11 Juin 2024
Using fread to read in binary containing 14bit ADC data streamed from an FPGA.
Wondering if fread does a cast when you use ubitn or bitn for the precision input.
Currently My fread setup similar to the code below spits out int16.
Output_data=fread(FID,Inf,'*bit14')
When I go to get this into a double will this int16 need to be bitsliced or cast.
0 commentaires
Réponse acceptée
Steven Lord
le 6 Juin 2024
MATLAB doesn't have a 14-bit integer type. The closest larger type is the signed 16-bit integer type int16. From the fread documentation, when you use the *source precision input argument: "For bitn or ubitn precisions, the output has the smallest class that can contain the input."
Can you clarify what you mean by "get this into a double"? Do you mean you want to cast the value from int16 to double? Or do you want to typecast the bit pattern? If the latter and you only want to work with 14 of the 16 bits in the int64 data returned by fread that could get a little tricky.
x = randi([intmin('int16'), intmax('int16')], 1, 8, 'int16')
castValue = double(x) % or
castValue = cast(x, 'double') % Same value as x, different type, different bit patterns
bitPattern = typecast(x, 'double') % Different values, different type, same bit patterns
whos x castValue bitPattern
Note that castValue has the same number of elements as x, but bitPattern has fewer. A 16-bit integer is stored in 2 bytes while a 64-bit double is stored in 8, so every 4 int16 values in x becomes 1 double in bitPattern. You can see the difference by looking at x, castValue, and bitPattern's hex representations.
format hex
x
castValue
bitPattern
3 commentaires
Andy Bartlett
le 11 Juin 2024
Modifié(e) : Andy Bartlett
le 11 Juin 2024
You can think of the internals of fread broken down into two steps.
Internal Step 1, read the VALUE from the file using the format specified.
Internal Step 2, convert the VALUE to the output type that was explicitly specified or implicitly determined.
So in your example, with '*bit14'
Internal Step 1 is to read a VALUE as type '*bit14'. Let's suppose the value is 1234.
Internal Step 2 convert the VALUE, 1234, to the implicit output type int16. Since the types are just integers (equivalently trivial fixed-point scaling), we don't have to worry about scaling changes; the real-world-values and stored-integer-values are same. Since the representable values of type int16 are a superset of the representable values in integer type signed 14 bits, the cast will be lossless. So we don't need to worry about overflows or rounding. If the input is 1234, then the output will be the identical value 1234.
If you want to think about it at the bit level, then the output would have two extra bits appended to the most significant end. These two extra bits will be a sign extension of the sign bit from the 14-bit input. So if the 14 bit input was non-negative, then the two extra bits on the most significant end will be 0's. If the the 14 bit input was negative, then the two extra bits on the most significant end of the output will be 1's.
If you wanted to get the value as a 14 bit fi object, you could just cast the output from fread.
outFread = int16(1234)
yFiS14 = fi(outFread,1,14,0)
% If the output should have fixed-point scaling
% just apply a reinterpretcast with the desired scaling.
fractionLength = 7;
nty = numerictype(1,14,fractionLength);
yFiScaled = reinterpretcast(yFiS14,nty)
ySI = yFiScaled.storedInteger
Plus de réponses (0)
Voir également
Catégories
En savoir plus sur Logical dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!