Reputation: 39
I have a int32_t number and i need to check if will it fit in int8 and in16 but when i try:
if (number ==(int32_t)((int8_t) number)) {
printf("%s %d\n","8", number);
} else if (number ==(int32_t)((int16_t) number)){
printf("%s %d\n","16", number);
Compiler says that first if statement is always true, but i don't know how to do it in other way, using only "==" and bits operations like << >>. and <stdint.h>.
Upvotes: 4
Views: 1192
Reputation: 6522
As mentioned in some of the comments, your original approach of just casting the values should work.
if (number == (int32_t)((int8_t) number)) {
printf("%s %d\n","8", number);
} else if (number == (int32_t)((int16_t) number)){
printf("%s %d\n","16", number);
}
However, if you are required to do bit manipulations yourself (which is a bit unclear from your comments), then here are some other possible options.
Unsigned values:
You could just mask off the upper bits, by using the 'and' operation &
with the maximum value for the smaller type.
If these numbers are both equal, it means the value would fit in the smaller type. If not, it means some of the upper bits were used (and got masked off) so the values would be unequal.
For instance, an 8-bit number maximum would be 11111111
or 255
.
#include <stdio.h>
#include <stdint.h>
if (number == (number & UINT8_MAX)) { // Mask off the upper 24 bits
printf("%s %d\n","8", number);
} else if (number == (number & UINT16_MAX)) { // Mask off the upper 16 bits
printf("%s %d\n","16", number);
}
Signed values:
For signed values, it's a bit trickier given your restrictions. Additionally, C/C++ do not appear to define a strict way of representing negative numbers, so it may vary by compiler. However, I believe my solution below should work for both one's complement and two's complement.
#include <stdio.h>
#include <stdint.h>
// Handle negative numbers by converting them to positive value.
// We will still need to handle the minimum (i.e. most negative) value, in
// case of two's complement.
int isNegative = ((originalNumber >> 31) != 0);
int positiveNumber = isNegative ? number * -1 : number;
if ((isNegative && (number == INT8_MIN)) ||
(positiveNumber == (positiveNumber & INT8_MAX))) {
printf("%s %d\n","8", number);
} else if ((isNegative && (number== INT16_MIN)) ||
(positiveNumber == (positiveNumber & INT16_MAX))) {
printf("%s %d\n","16", number);
}
Upvotes: 2
Reputation: 66371
If the number is positive, you can mask out the bottom 8 or 16 bits and compare.
If the number is negative, you have:
So, something like this, perhaps:
char* answer[] = { "no", "yes" };
if (!(number >> 31))
{
printf("Fits in eight: %s\n", answer[number == (number & 0xff)]);
printf("Fits in 16: %s\n", answer[number == (number & 0xffff)]);
}
else
{
printf("Fits in eight: %s\n", answer[(number >> 7) == 0x1ffffff]);
printf("Fits in 16: %s\n", answer[(number >> 15) == 0x1ffff]);
}
Upvotes: 1
Reputation: 238351
How to check if int32_t number can fit in int8_t and int16_t?
Like this:
extern std::int32_t value;
if (value <= std::numeric_limits<std::int8_t>::max()
&& value >= std::numeric_limits<std::int8_t>::min())
I expect std::int16_t
case to be trivial based on this.
Since C++20, there is a simpler solution.
Upvotes: 2