What is the difference between int8(0x98), uint8(0x98), typecast(uint8(0x98), 'int8')

>> A=int8(0x98)
A =
int8
127
>> B=uint8(0x98)
B =
uint8
152
>> C=typecast(uint8(0x98), 'int8')
C =
int8
-104
I want 0x98 to be handled as signed Integer. Expectation is a negative values (-104) - two's complement.
Why is the calculation A=int8(0x98) leading to 127 and not to -104.

3 Comments

"Why is the calculation A=int8(0x98) leading to 127 and not to -104."
From the documentation of int8 - "Y = int8(X) converts the values in X to type int8. Values outside the range [-2^7,2^7-1] map to the nearest endpoint."
Additionally, from the documentation of typecast - "Y = typecast(X,type) converts the bit patterns of X to the data type specified by type without changing the underlying data."
format hex
A=int8(0x98)
A = int8
7f
B=uint8(0x98)
B = uint8
98
C=typecast(B, 'int8')
C = int8
98
If you use cast, the result is same as the behaviour of the data type of the converted class.
C0=cast(B,'int8')
C0 = int8
7f
All of above is understood.
The ind8 value range is specified to be [-2^7,2^7-1].
How do I get the negative values?
I don't understand, is using typecast() not satisfactory?
Or am I misunderstanding what you want to obtain? In that case, please specify.
A=int8(0x98)
A = int8 127
B=uint8(0x98)
B = uint8 152
C=typecast(B, 'int8')
C = int8 -104

Sign in to comment.

Answers (2)

If you use the following syntax, you create a uint8 value and then cast that value to int8. Since the uint8 value is larger than intmax for int8, it saturates at intmax.
y1 = 0x98
y1 = uint8 152
z = int8(y1)
z = int8 127
Why uint8 not int8? From that documentation page I linked above: "By default, MATLAB stores the number as the smallest unsigned integer type that can accommodate it."
Instead tell MATLAB you want an int8 (a signed 8-bit integer) value from the start. To do this add the "s8" suffix to the hex value.
y2 = 0x98s8
y2 = int8 -104
The typecast function works because it converts not the value stored in the input but the bit pattern of the input to the new type.
format hex % Show the hex digits of the bit pattern
y1
y1 = uint8
98
y2
y2 = int8
98
In MATLAB, the number 0x98 will be represented as 127 in int8 due to overflow.
It will map to the nearest endpoint of the range. This is how MATLAB handles the overflow instead of setting the sign bit, like you would see in C.
However while typcasting a uint to int, it does not truncate and keeps the last bit. Hence you get -104
Read the description in this page to understand it better: int8

5 Comments

int8 explains the following:
Y = int8(X) converts the values in X to type int8. Values outside the range [-2^7,2^7-1] map to the nearest endpoint.
Integers: explains that matlab distiguishes between unsigned (uint) and signed (int).
To all what I experience is that Y = int8(X) ignores the MSB and maps to 2^7-1 in case x>=127.
Expected behaviour would have been that the MSB triggers the 2th-complement calculation to deliver the negative values down to -2^7.
I have the impression that in my version MATLAB R2022b the Y = int8(X) is not implemented as described in int8. Is this a known limitation/bug?
Please describe why not using the defined range [-2^7,2^7-1] is intended behavior.
"I have the impression that in my version MATLAB R2022b the Y = int8(X) is not implemented as described in int8."
I doubt there is a difference in the behaviour of int8 in your version and the one ran above in the comment I posted (R2023a).
"Expected behaviour would have been that the MSB triggers the 2th-complement calculation to deliver the negative values down to -2^7."
Please take a look at @Steven Lord's (informative) answer. It explains the behaviour of MATLAB w.r.t the issue of discussion.
To all what I experience is that Y = int8(X) ignores the MSB and maps to 2^7-1 in case x>=127.
It sounds like you expected that conversion to wrap. It does not. It saturates at intmax.
To forestall what I expect will be your next question no, there is no way to change how MATLAB performs integer conversion or arithmetic to make it wrap instead of saturate.
my takeaaway:
y=int8(x) is not implemented as one might understand from the documentation int8: signed integer with number range [-2^7 .. 2^7-1]
  • The number range is limited to [0 .. 2^7-1]
  • The defined number range [-2^7 .. -1] cannot be achieved: value saturates at 2^7-1 instead
  • negative sign is not provided
Several workarounds are present to generate a signed interger among which:
  • y=typecast(uint8(x), 'int8')
  • "s8"-suffix to HEX-number
  • ...
I consider this topic closed.
The number range is limited to [0 .. 2^7-1]
The range of values that can be represented in the int8 data type is:
[intmin('int8'), intmax('int8')]
ans = 1×2
-128 127
where 2^7-1 is:
2^7-1
ans = 127
So your statement is incorrect.
The defined number range [-2^7 .. -1] cannot be achieved: value saturates at 2^7-1 instead
Incorrect. If you try to cast a uint8 value to int8, anything greater than intmax of int8 becomes intmax of int8.
y = intmax('uint8')
y = uint8 255
z1 = int8(y)
z1 = int8 127
If you try to typecast a uint8 bit pattern to int8 then you can easily obtain a negative int8 value.
z2 = typecast(y, 'int8')
z2 = int8 -1
But you can certainly create negative int8 values directly
y = int8(-1)
y = int8 -1
negative sign is not provided
Incorrect, as shown above.

Sign in to comment.

Categories

Find more on Sparse Matrices in Help Center and File Exchange

Asked:

on 6 Jun 2023

Edited:

on 7 Jun 2023

Community Treasure Hunt

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

Start Hunting!