[英]Printing the actual negative number stored inside unsigned int
I have a strange problem. 我有一个奇怪的问题。 I have a variable whose actual value is only negative(only negative integers are generated for this variable).
我有一个变量的实际值仅为负(此变量仅生成负整数)。 But in the legacy code, an old colleague of mine used uint16 instead of signed int to store the values of that variable.
但是在旧版代码中,我的一位老同事使用uint16而不是signed int来存储该变量的值。 Now if i wanted to print the actual negative value of that variable, how can i do that(what format specifier to us)?
现在,如果我想打印该变量的实际负值,我该怎么做(给我们什么格式的说明符)? For example if actual value is -75, when i print using %d its giving me 5 digit positive value(I think its because of two's complement).
例如,如果实际值为-75,则当我使用%d打印时,它给了我5位数的正值(我认为是因为有两个补码)。 I want to print it as 75 or -75.
我想将其打印为75或-75。
If an int
is 32 bits on your system, then the correct format for printing a 16-bit int is %hu
for unsigned and %hd
for signed. 如果系统上的
int
是32位,则打印16位int的正确格式是%hu
表示无符号)和%hd
表示带符号)。
Examine the output of: 检查以下内容的输出:
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
Assuming your friend has somehow correctly put the bit representation for the signed integer into the unsigned integer, the only standard compliant way to extract it back would be to use a union as- 假设您的朋友以某种方式正确地将有符号整数的位表示形式放入无符号整数中,则将其提取回来的唯一符合标准的方法是使用联合作为-
typedef union {
uint16_t input;
int16_t output;
} aliaser;
Now, in your code you can do - 现在,在您的代码中,您可以-
aliaser x;
x.input = foo;
printf("%d", x.output);
#include <inttypes.h>
uint16_t foo = -75;
printf("==> %" PRId16 " <==\n", foo); // type mismatch, undefined behavior
If a 16-bit negative integer was stored in a uint16_t
called x
, then the original value may be calculated as x-65536
. 如果将16位负整数存储在称为
x
的uint16_t
,则原始值可以计算为x-65536
。
This can be printed with any of 1 : 这可以印有任何的1:
printf("%ld", x-65536L);
printf("%d", (int) (x-65536));
int y = x-65536;
printf("%d", y);
Subtracting 65536 works because: 减去65536的原因是:
uint16_t
, one more than its maximum is 65536. uint16_t
,比最大值uint16_t
多一个。 uint16_t
. uint16_t
的范围。 1 65536
will be long
or int
according to whether int
is 16 bits or more, so these statements are careful to handle the type correctly. 1
65536
根据int
是16位还是更多位而为long
或int
,因此这些语句要小心处理正确的类型。 The first uses 65536L
to ensure the type is long
. 第一种使用
65536L
以确保类型long
。 The rest convert the value to int
. 其余的将值转换为
int
。 This is safe because, although the type of x-65536
could be long
, its value fits in an int
—unless you are executing in a C implementation that limits int
to −32767 to +32767, and the original value may be −32768, in which case you should stick to the first option. 这是安全的,因为尽管
x-65536
的类型可能很long
,但其值适合int
除非您正在将int
限制为-32767到+32767的C实现中执行,并且原始值可能是-32768,在这种情况下,您应该坚持第一个选择。
Go ahead with the union, as explained by another answer. 如另一个答案所述,继续进行工会。 Just wanted to say that if you are using GCC, there's a very cool feature that allows you to do that sort of "bitwise" casting without writing much code:
只是想说,如果您使用的是GCC,则有一个非常酷的功能,使您无需编写太多代码即可进行这种“按位”转换:
printf("%d", ((union {uint16_t in; int16_t out}) foo).out);
See https://gcc.gnu.org/onlinedocs/gcc-4.4.1/gcc/Cast-to-Union.html . 参见https://gcc.gnu.org/onlinedocs/gcc-4.4.1/gcc/Cast-to-Union.html 。
If u
is an object of unsigned integer type and a negative number whose magnitude is within range of u
's type is stored into it, storing -u
to an object of u
's type will leave it holding the magnitude of that negative number. 如果
u
是无符号整数类型的对象,并且将大小在u
类型范围内的负数存储在其中,则将-u
存储到u
类型的对象将使其保持该负数的大小。 This behavior does not depend upon how u
is represented. 此行为不取决于
u
的表示方式。 For example, if u
and v
are 16-bit unsigned short
, but int
is 32 bits, then storing -60000 into u
will leave it holding 5536
[the implementation will behave as though it adds 65536 to the value stored until it's within range of unsigned short
]. 例如,如果
u
和v
是16位unsigned short
,但int
是32位,则将-60000存储到u
中将使它保持5536
[实现的行为就像将65536添加到存储的值中,直到它在unsigned short
]。 Evaluating -u
will yield -5536, and storing -5536 into v
will leave it holding 60000. 计算
-u
将产生-5536,将-5536存储到v
中将保留60000。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.