Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 打印存储在unsigned int中的实际负数_C - Fatal编程技术网

C 打印存储在unsigned int中的实际负数

C 打印存储在unsigned int中的实际负数,c,C,我有一个奇怪的问题。我有一个变量,它的实际值只有负值(这个变量只生成负整数)。但是在遗留代码中,我的一位老同事使用uint16而不是带符号的int来存储该变量的值。现在,如果我想打印该变量的实际负值,我该怎么做(我们使用什么格式说明符)?例如,如果实际值为-75,当我使用%d打印时,它会给我5位数的正值(我认为这是因为2的补码)。我想把它打印成75或-75 如果系统上的int为32位,则打印16位int的正确格式为%hu表示无符号,而%hd表示有符号 检查以下各项的输出: uint16_t n

我有一个奇怪的问题。我有一个变量,它的实际值只有负值(这个变量只生成负整数)。但是在遗留代码中,我的一位老同事使用uint16而不是带符号的int来存储该变量的值。现在,如果我想打印该变量的实际负值,我该怎么做(我们使用什么格式说明符)?例如,如果实际值为-75,当我使用%d打印时,它会给我5位数的正值(我认为这是因为2的补码)。我想把它打印成75或-75

如果系统上的
int
为32位,则打印16位int的正确格式为
%hu
表示无符号,而
%hd
表示有符号

检查以下各项的输出:

uint16_t n = (uint16_t)-75;

printf("%d\n", (int)n); // Output: 65461
printf("%hu\n", n); // Output: 65461
printf("%hd\n", n); // Output: -75

如果系统上的
int
为32位,则打印16位int的正确格式为
%hu
表示未签名,而
%hd
表示已签名

检查以下各项的输出:

uint16_t n = (uint16_t)-75;

printf("%d\n", (int)n); // Output: 65461
printf("%hu\n", n); // Output: 65461
printf("%hd\n", n); // Output: -75

假设您的朋友以某种方式正确地将有符号整数的位表示形式转换为无符号整数,那么将其提取回来的唯一符合标准的方法是使用并集作为-

typedef union {
    uint16_t input;
    int16_t output;
} aliaser;

现在,在您的代码中,您可以执行-

aliaser x;
x.input = foo;
printf("%d", x.output);

假设您的朋友以某种方式正确地将有符号整数的位表示形式转换为无符号整数,那么将其提取回来的唯一符合标准的方法是使用并集作为-

typedef union {
    uint16_t input;
    int16_t output;
} aliaser;

现在,在您的代码中,您可以执行-

aliaser x;
x.input = foo;
printf("%d", x.output);

正如另一个答案所解释的那样,继续与工会合作。我想说的是,如果您使用的是GCC,那么有一个非常酷的特性可以让您在不编写太多代码的情况下进行“按位”转换:

printf("%d", ((union {uint16_t in; int16_t out}) foo).out);

请参阅。

按照另一个答案的解释,继续工会。我想说的是,如果您使用的是GCC,那么有一个非常酷的特性可以让您在不编写太多代码的情况下进行“按位”转换:

printf("%d", ((union {uint16_t in; int16_t out}) foo).out);
请参阅。

#包括
uint16_t foo=-75;
printf(“==>%”PRId16“
#包括
uint16_t foo=-75;

printf(“==>%”“PRId16”如果在名为
x
uint16\u t
中存储了16位负整数,则原始值可计算为
x-65536

可以使用以下任意一种打印:

减去65536有效,因为:

  • 根据C 2018 6.5.16.1 2,右操作数的值(负16位整数转换为赋值表达式的类型(本质上是左操作数的类型)
  • 根据6.3.1.3.2,向无符号整数的转换通过“比新类型中可表示的最大值多出一个”的加或减操作。对于
    uint16\u t
    ,比其最大值多出一个是65536
  • 对于一个16位负整数,加65536一次将使其进入
    uint16\u t
    的范围
  • 因此,减去65536将恢复原始值
脚注
根据
int
是否为16位或更多,1
65536
将为
long
int
,因此这些语句小心地正确处理类型。第一个语句使用
65536L
确保类型为
long
。其余语句将值转换为
int
。这是安全的,因为
x-65536
的类型可以是
long
,其值适合
int
——除非您在限制
int
为−32767到+32767,原始值可能为−32768,在这种情况下,您应该坚持使用第一个选项。

如果在名为
x
uint16\u t
中存储了一个16位负整数,则原始值可以计算为
x-65536

可以使用以下任意一种打印:

减去65536有效,因为:

  • 根据C 2018 6.5.16.1 2,右操作数的值(负16位整数转换为赋值表达式的类型(本质上是左操作数的类型)
  • 根据6.3.1.3.2,向无符号整数的转换通过“比新类型中可表示的最大值多出一个”的加或减操作。对于
    uint16\u t
    ,比其最大值多出一个是65536
  • 对于一个16位负整数,加65536一次将使其进入
    uint16\u t
    的范围
  • 因此,减去65536将恢复原始值
脚注
根据
int
是否为16位或更多,1
65536
将为
long
int
,因此这些语句小心地正确处理类型。第一个语句使用
65536L
确保类型为
long
。其余语句将值转换为
int
。这是安全的,因为
x-65536
的类型可以是
long
,其值适合
int
——除非您在限制
int
为−32767到+32767,原始值可能为−32768,在这种情况下,您应该坚持第一个选项。

如果
u
是一个无符号整数类型的对象,并且将大小在
u
类型范围内的负数存储到该对象中,则将
-u
存储到
u
类型的对象将保留该负数的大小。此behavior不取决于
u
的表示方式。例如,如果
u
v
为16位
无符号短
,但
int
为32位,则将-60000存储到
u
中将使其保持
5536
[该实现的行为就像将65536添加到存储的值中,直到它在
无符号短
]的范围内。计算
-u
将得到-5536,将-5536存储到
v
中将使其保持60000。

如果
u
是无符号整数类型的对象,则