繁体   English   中英

如何检查 int32_t 数字是否适合 int8_t 和 int16_t?

[英]How to check if int32_t number can fit in int8_t and int16_t?

我有一个 int32_t 号码,我需要检查它是否适合 int8 和 in16 但是当我尝试时:

    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);
    

编译器说第一个 if 语句总是正确的,但我不知道如何以其他方式做到这一点,只使用“==”和像 << >> 这样的位操作。 和 <stdint.h>。

从 C++ 20 开始,您可以这样做:

std::in_range<std::int8_t>(-1)

这里

如何检查 int32_t 数字是否适合 int8_t 和 int16_t?

像这样:

extern std::int32_t value;

if (value <= std::numeric_limits<std::int8_t>::max()
 && value >= std::numeric_limits<std::int8_t>::min())

基于此,我希望std::int16_t案例是微不足道的。


从 C++20 开始,有一个更简单的解决方案

正如一些评论中提到的,您最初的仅转换值的方法应该有效。

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);
}

但是,如果您需要自己进行位操作(您的评论有点不清楚),那么这里有一些其他可能的选择。

无符号值:

您可以通过使用“与”操作&来屏蔽高位,并使用较小类型的最大值。

如果这两个数字相等,则意味着该值适合较小的类型。 如果不是,则意味着使用了一些高位(并被屏蔽),因此值将不相等。

例如,最大 8 位数为11111111255

#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);
}

签名值:

对于有符号值,考虑到您的限制,这有点棘手。 此外,C/C++ 似乎没有定义表示负数的严格方式,因此它可能因编译器而异。 但是,我相信我下面的解决方案应该适用于一个补码和二进制补码。

#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);
}

如果数字是正数,您可以屏蔽掉底部的 8 位或 16 位并进行比较。
如果该数字为负数,则您有:

  • 对于 -1 和 -128 之间的数字(适合 8 位),前 25 位都已设置。
  • 从 -129 及以下,前 25 位中至少有一个零。
  • 对于介于 -1 和 -32768 之间的数字(适合 16 位),最高 17 位均已设置。
  • 从 -32769 开始,前 17 位中至少有一个零。

所以,像这样的东西,也许:

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]);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM