[bug] boolean to uint8
18 views (last 30 days)
Show older comments
Nathan Zimmerman
on 9 Aug 2017
Edited: Walter Roberson
on 8 Feb 2018
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
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
Walter Roberson
on 14 Aug 2017
No, MATLAB is not going to address this. typecast() involves re-interpreting representation, but MATLAB does not publicly define the representation of logical (or boolean). As far as the user is concerned, a vector of logical values might be internally implemented as a packed array of bits, or might be implemented as bytes where 0 is false and all-ones is true, or where 0 is false and true has only the top bit set in the byte, or by some other method.
MATLAB also does not permit typecast between numeric values and char. This ambiguity allowed them to move from 8 bit characters to 16 bit characters without change to the user interface; at some point Mathworks might switch to 32 bit characters to permit full Unicode.
Historically, PASCAL did not offer any typecast operation, and logical values were an enumerated type. In the implementation I programmed in (decades ago), logical true was internally represented as a byte of all 1's, because the processor family we were using (Motorola MC68020) was one cycle faster at Test For Negative than it was for Test For Non Zero.
5 Comments
Walter Roberson
on 15 Aug 2017
Edited: Walter Roberson
on 8 Feb 2018
uint8 or int8 for boolean values is not standard.
C11-§6.5.9/3:
The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence.108) Each of the operators yields 1 if the specified relation is true and 0 if it is false. The result has type int.
If you follow through the various standards historically, type int is never less than 16 (signed) bits.
Historically there was no int8 or uint8, and in order to get them you had to use type "signed char" (very rare to see in practice unless you were working with early Sun computers) or "unsigned char", as char was defined as being the smallest addressable integer type -- which explicitly does mean that char is 16 bits on some platforms, since some DSPs cannot address individual bytes.
James Tursa
on 16 Aug 2017
Edited: James Tursa
on 16 Aug 2017
"... MATLAB does not publicly define the representation of logical (or boolean)..."
Actually they do expose that publicly (sort of) at the mex level, since they explicitly document the mxLogical macro (or typedef) as the element type used in MATLAB logical variables. So that probably eliminates the possibility that packed arrays of bits could be the underlying storage method used. As to the supported "values" of these underlying bits in MATLAB functions, I don't know if that is explicitly documented anywhere. See my comment to Jan's answer.
Similar comments for char variables since MATLAB exposes that in the mex API interface with the mxChar macro (or typedef).
More Answers (3)
Jan
on 14 Aug 2017
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 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.
0 Comments
Image Analyst
on 14 Aug 2017
Use cast() instead of typecast():
output = cast(logical(0),'uint8')
0 Comments
See Also
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!