在 C 中以十六进制级别拆分 int?
Split int on hexadecimal level in C?
我正在尝试从图像缓冲区中提取一些颜色代码。当我从缓冲区中读出一个内存地址时,它 returns 一个包含两个像素颜色代码的 int 值。我的目标是将每个颜色代码作为一个单独的 int 值。
例如,当我从图像缓冲区中读出内存地址时,它returns十进制值:142149753。
因为这个十进制值有 9 个字符长,所以我不能简单地将它分解为两个 int 值。因此,我尝试使用 printf 函数将该值转换为十六进制,该函数给出了值:08790879.
现在我可以看到我需要的两个 16 位颜色代码:0879 和 0879。
int firstColorCode;
int secondColorCode;
int colorcodes = IORD_ALTERA_AVALON_PIO_DATA(0x08000000 + 123204);
printf("%08x\n", colorcodes);
如何在代码中将两个颜色代码分别放入对应的int变量中?
免责声明:我是 C 的新手,感觉我在问一个愚蠢的问题:/
您需要使用右移来获取第一个颜色代码。对于第二个颜色代码,您需要使用 uint16_t
进行屏蔽或类型转换
firstColorCode = (uint16_t) (colorcodes >> 16u);
secondColorCode = (uint16_t) colorcodes;
你也可以使用,
firstColorCode = (colorcodes >> 16u) & 0xFFFFu;
secondColorCode = colorcodes & 0xFFFFu;
您应该为颜色代码使用 unsigned int 值,以避免在右移中出现未定义的行为。
uint16_t firstColorCode;
uint16_t secondColorCode;
uint32_t colorcodes;
此外,正如@lundin 所建议的,我已将 u
添加到常量中,使它们成为无符号常量。
走C型系统雷区有一些基本规则:
- 在进行任何形式的按位操作时,切勿使用有符号类型。
- 当您实际上不需要负数时,切勿使用有符号类型。
- 使用
char
、short
、uint16_t
等小整数类型时要小心,因为它们在表达式中使用时会隐式提升为有符号 int
。
有关隐式促销的更多信息:
- 警惕十六进制文字,因为它们有各种关于获得哪种类型的微妙规则。始终在它们后缀
u
以防止它们成为签名类型。
- 永远不要在 C 代码中写前导零。如果你在C中写类似
0879
的东西,它表示八进制格式。
通过更加注意类型,我们可以像这样将您的 32 位数字一分为二:
#include <stdint.h>
uint16_t first;
uint16_t second;
uint32_t colorcodes = IORD_ALTERA_AVALON_PIO_DATA(0x8000000u + 123204u);
first = (uint16_t) (colorcodes >> 16);
second = (uint16_t) colorcodes;
使用 printf("%"PRIx16, first)
从 inttypes.h
.
将 uint16_t
打印为十六进制
只需将数字除以 65536
。余数将是你一半的下半部分,商是最重要的部分。
顺便说一句,一些关于使用无符号值的评论的想法也很好,并且考虑将 unsigned int
数字右移 16
相当于除以 2^16 == 65536
.
我正在尝试从图像缓冲区中提取一些颜色代码。当我从缓冲区中读出一个内存地址时,它 returns 一个包含两个像素颜色代码的 int 值。我的目标是将每个颜色代码作为一个单独的 int 值。
例如,当我从图像缓冲区中读出内存地址时,它returns十进制值:142149753。
因为这个十进制值有 9 个字符长,所以我不能简单地将它分解为两个 int 值。因此,我尝试使用 printf 函数将该值转换为十六进制,该函数给出了值:08790879.
现在我可以看到我需要的两个 16 位颜色代码:0879 和 0879。
int firstColorCode;
int secondColorCode;
int colorcodes = IORD_ALTERA_AVALON_PIO_DATA(0x08000000 + 123204);
printf("%08x\n", colorcodes);
如何在代码中将两个颜色代码分别放入对应的int变量中?
免责声明:我是 C 的新手,感觉我在问一个愚蠢的问题:/
您需要使用右移来获取第一个颜色代码。对于第二个颜色代码,您需要使用 uint16_t
firstColorCode = (uint16_t) (colorcodes >> 16u);
secondColorCode = (uint16_t) colorcodes;
你也可以使用,
firstColorCode = (colorcodes >> 16u) & 0xFFFFu;
secondColorCode = colorcodes & 0xFFFFu;
您应该为颜色代码使用 unsigned int 值,以避免在右移中出现未定义的行为。
uint16_t firstColorCode;
uint16_t secondColorCode;
uint32_t colorcodes;
此外,正如@lundin 所建议的,我已将 u
添加到常量中,使它们成为无符号常量。
走C型系统雷区有一些基本规则:
- 在进行任何形式的按位操作时,切勿使用有符号类型。
- 当您实际上不需要负数时,切勿使用有符号类型。
- 使用
char
、short
、uint16_t
等小整数类型时要小心,因为它们在表达式中使用时会隐式提升为有符号int
。
有关隐式促销的更多信息: - 警惕十六进制文字,因为它们有各种关于获得哪种类型的微妙规则。始终在它们后缀
u
以防止它们成为签名类型。 - 永远不要在 C 代码中写前导零。如果你在C中写类似
0879
的东西,它表示八进制格式。
通过更加注意类型,我们可以像这样将您的 32 位数字一分为二:
#include <stdint.h>
uint16_t first;
uint16_t second;
uint32_t colorcodes = IORD_ALTERA_AVALON_PIO_DATA(0x8000000u + 123204u);
first = (uint16_t) (colorcodes >> 16);
second = (uint16_t) colorcodes;
使用 printf("%"PRIx16, first)
从 inttypes.h
.
uint16_t
打印为十六进制
只需将数字除以 65536
。余数将是你一半的下半部分,商是最重要的部分。
顺便说一句,一些关于使用无符号值的评论的想法也很好,并且考虑将 unsigned int
数字右移 16
相当于除以 2^16 == 65536
.