[bug] boolean to uint8
Show older comments
To my knowledge, matlab is the only coding language on the planet cannot convert a boolean to a byte.
typecast(boolean(0),'uint8')
or
typecast(logical(0),'uint8')
yields:
Error using typecast
The first input argument must be a full, non-complex numeric value.
Granted, there are easy hack-a-rounds to get past this but its frustrating to have to use them. I am using 2016A. Will/has matlab ever addressed this?
6 Comments
Nathan Zimmerman
on 9 Aug 2017
Philip Borghesani
on 14 Aug 2017
I can't think of a use case where you would need or want to do this. What is your use case? Why would typecast be better then cast or other solutions?
Jan
on 14 Aug 2017
@Philip: typecast creates a shared data copy, such that this can be much more efficient.
@Nathan: This is definitely not a bug, but it differs from your expectations only.
Nathan Zimmerman
on 15 Aug 2017
Walter Roberson
on 16 Aug 2017
If the structure to be packed has components that are not constant size or not constant type, then perhaps you should use one of the serialization routines from the File Exchange.
Accepted Answer
More Answers (3)
Jan
on 14 Aug 2017
1 vote
If you need to typecast logical to uint8, use https://www.mathworks.com/matlabcentral/fileexchange/17476-typecast-and-typecastx-c-mex-functions. This creates a shared data copy as modern versions of typecast, but allows char,logical and non-vector arrays also.
If Matlab changes the internal format of logicals, this function might crash tremendously, but this is not expected yet.
3 Comments
James Tursa
on 15 Aug 2017
Edited: James Tursa
on 15 Aug 2017
Current version of typecastx does have char and logical bytes-per-element hard coded to 2 and 1 respectively for output ... the input bytes-per-element is obtained dynamically from the API function mxGetElementSize. So yes, if things change in the future, then typecastx would produce incorrect results for the output. I can look into making this more robust with sizeof(mxChar) and sizeof(mxLogical) (although I can't imagine why the logical type would ever change from 1 byte).
James Tursa
on 16 Aug 2017
Edited: James Tursa
on 16 Aug 2017
I will add another comment here about the behavior of typecastx when producing logical values. The bit pattern carries over intact since it is a shared data copy, so the resulting class will be logical, but the underlying bit patterns will display and be used as unsigned integers (at least in the MATLAB versions that I have used). E.g.,
>> g = typecastx(int8(-3:3),'logical')
g =
253 254 255 0 1 2 3
>> class(g)
ans =
logical
>> g == true
ans =
0 0 0 0 1 0 0
>> g(1) == 253
ans =
1
>> if( g(1) ); disp('g(1) is true'); end
g(1) is true
>> if( g(6) ); disp('g(6) is true'); end
g(6) is true
>> g * 2
ans =
506 508 510 0 2 4 6
>> class(ans)
ans =
double
So, only the particular element of g that is exactly 1 (i.e., g(5)) will equate exactly with the "true" function result. But when used in control statements all of the non-zero values are regarded as logically "true".
Of course, in a mex routine one could simply create a logical variable with element values other than 0 or 1 directly ... no shared data copy stuff needed for that. But I would have to think that all of the MATLAB functions dealing with logical variables assume the underlying element values are either 0 or 1 explicitly. So using logical variables with other underlying element values should probably be regarded as undocumented behavior and should not relied on. Avoiding this type of behavior may be the exact reason MATLAB does not allow conversion to logical in their typecast function.
Jan
on 16 Aug 2017
@James: In my opinion, typecastx works perfect and it is not a problem, that the implementation does not consider a potential change of logicals to packed binary variables. It need not to be fixed, because it is not broken.
It is interesting, that the conversion
L = typecastx(int8(2), 'logical')
is not recognized as true. This is a pitfall when using typecastx without the required care. This might be one of the reasons why MathWorks decided not to accept logicals in the built-in typecast.
Jayaram Theegala
on 14 Aug 2017
Edited: Jayaram Theegala
on 14 Aug 2017
If you want to convert any numeric class type to "uint8" datatype, you can use the "uint8" function. For more information, click on the following MATLAB documentation: https://www.mathworks.com/help/matlab/ref/uint8.html
logicalArr = logical([1,0,0,1,1]);
typecastedArr = uint8(logicalArr);
You may find the above MATLAB code snippet helpful.
Image Analyst
on 14 Aug 2017
Use cast() instead of typecast():
output = cast(logical(0),'uint8')
Categories
Find more on Logical in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!