C语言 将负数分配给无符号整数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5169692/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 07:56:43  来源:igfitidea点击:

Assigning negative numbers to an unsigned int?

c

提问by ipkiss

In the C programming language, unsigned intis used to store positive values only. However, when I run the following code:

在 C 编程语言中,unsigned int仅用于存储正值。但是,当我运行以下代码时:

unsigned int x = -12;
printf("%d", x);

The output is still -12. I thought it should have printed out: 12, or am I misunderstanding something?

输出仍然是-12。我认为它应该打印出来:12,还是我误解了什么?

回答by Tim Oltrogge

The -12to the right of your equals sign is set up as a signed integer (probably 32 bits in size) and will have the hexadecimal value 0xFFFFFFF4. The compiler generates code to move this signed integer into your unsigned integer xwhich is also a 32 bit entity. The compiler assumes you only have a positive value to the right of the equals sign so it simply moves all 32 bits into x. xnow has the value 0xFFFFFFF4which is 4294967284if interpreted as a positive number. But the printfformat of %dsays the 32 bits are to be interpreted as a signed integer so you get -12. If you had used %uit would have printed as 4294967284.

-12您等号的右边被设置为一个有符号整数(大小大概32位),将有十六进制值0xFFFFFFF4。编译器生成代码以将这个有符号整数移动到x同样是 32 位实体的无符号整数中。编译器假定等号右侧只有一个正值,因此它只是将所有 32 位移动到x. x现在具有值0xFFFFFFF44294967284如果解释为正数。但是printf格式%d说 32 位将被解释为有符号整数,所以你得到-12. 如果您使用过%u它,它会打印为4294967284.

In either case you don't get what you expected since C language "trusts" the writer of code to only ask for "sensible" things. This is common in C. If you wanted to assign a value to xand were not sure whether the value on the right side of the equals was positive you could have written unsigned int x = abs(-12);and forced the compiler to generate code to take the absolute value of a signed integer before moving it to the unsigned integer.

在任何一种情况下,您都不会得到预期的结果,因为 C 语言“信任”代码编写者只要求“明智”的事情。这在 C 中很常见。如果您想为其分配一个值x并且不确定等号右侧的值是否为正,您可以编写unsigned int x = abs(-12);并强制编译器生成代码以获取有符号整数的绝对值在将其移动到无符号整数之前。

回答by Binary Worrier

The int is unsinged, but you've told printfto look at it as a signed int.

int 是未标记的,但您已经告诉printf将其视为有符号的 int。

Try

尝试

unsigned int x = -12; printf("%u", x);

It won't print "12", but will print the max value of an unsigned int minus 11.

它不会打印“12”,但会打印 unsigned int 减去 11 的最大值。

Exercise to the reader is to find out why :)

给读者的练习是找出原因:)

回答by Erik

Passing %d to printf tells printf to treat the argument as a signed integer, regardless of what you actually pass. Use %u to print as unsigned.

将 %d 传递给 printf 告诉 printf 将参数视为有符号整数,而不管您实际传递的是什么。使用 %u 打印为无符号。

回答by EvilTeach

It all has to do with interpretation of the value.

这一切都与价值的解释有关。

If you assume 16 bit signed and unsigned integers, then here some examples that aren't exactly correct, but demonstrate the concept.

如果你假设 16 位有符号和无符号整数,那么这里有一些不完全正确的例子,但演示了这个概念。

0000 0000 0000 1100 unsigned int, and signed int value 12

0000 0000 0000 1100 unsigned int 和 signed int 值 12

1000 0000 0000 1100 signed int value -12, and a large unsigned integer.

1000 0000 0000 1100 有符号整数值 -12,以及一个大的无符号整数。

For signed integers, the bit on the left is the sign bit. 0 = positive 1 = negative

对于有符号整数,左边的位是符号位。0 = 正 1 = 负

For unsigned integers, there is no sign bit. the left hand bit, lets you store a larger number instead.

对于无符号整数,没有符号位。左边的位,让你存储更大的数字。

So the reason you are not seeing what you are expecting is that.

所以你没有看到你期望的原因是。

unsigned int x = -12, takes -12 as an integer, and stores it into x. x is unsigned, so what was a sign bit, is now a piece of the value.

unsigned int x = -12,取-12为整数,存入x。x 是无符号的,所以什么是符号位,现在是值的一部分。

printf lets you tell the compiler how you want a value to be displayed.

printf 可让您告诉编译器您希望如何显示值。

%d means display it as if it were a signed int. %u means display it as if it were an unsigned int.

%d 表示将它显示为一个有符号整数。%u 表示将它显示为一个无符号整数。

c lets you do this kind of stuff. You the programmer are in control.

c 可以让你做这种事情。你是程序员。

Kind of like a firearm. It's a tool. You can use it correctly to deal with certain situations, or incorrectly to remove one of your toes.

有点像枪械。它是一个工具。您可以正确使用它来处理某些情况,也可以错误地使用它来去除您的一个脚趾。

one possibly useful case is the following

一个可能有用的案例如下

unsigned int allBitsOn = -1;

unsigned int allBitsOn = -1;

That particular value sets all of the bits to 1

该特定值将所有位设置为 1

1111 1111 1111 1111

1111 1111 1111 1111

that can be useful sometimes.

这有时很有用。

回答by Linus Kleen

printf('%d', x); 

Means print a signed integer. You'll have to write this instead:

表示打印一个有符号整数。你必须这样写:

printf('%u', x);

Also, it'll still not print "12", it's going to be "4294967284".

此外,它仍然不会打印“12”,而是“4294967284”。

回答by Lightness Races in Orbit

They do store positive values. But you're outputting the (very high) positive value as a signed integer, so it gets re-interpreted again (in an implementation-defined fashion, I might add).

它们确实存储了正值。但是您将(非常高的)正值输出为有符号整数,因此它会再次被重新解释(以实现定义的方式,我可能会补充)。

Use the format flag "%uinstead.

请改用格式标志"%u

回答by R.. GitHub STOP HELPING ICE

Your program has undefined behavior because you passed the wrong type to printf(you told it you were going to pass an intbut you passed an unsigned int). Consider yourself lucky that the "easiest" thing for the implementation to do was just silently print the wrong value and not jump to some code that does something harmful...

你的程序有未定义的行为,因为你传递了错误的类型printf(你告诉它你要传递 anint但你传递了一个unsigned int)。认为自己很幸运,实现要做的“最简单”的事情就是默默地打印错误的值,而不是跳转到一些有害的代码......

回答by Elemental

What you are missing is that the printf("%d",x) expects x to be signed, so although you assign -12 to x it is interpreted as 2's complement which would be a very large number. However when you pass this really large number to printf it interprets it as signed thus correctly translating it back to -12.

您缺少的是 printf("%d",x) 期望 x 有符号,因此尽管您将 -12 分配给 x 它被解释为 2 的补码,这将是一个非常大的数字。但是,当您将这个非常大的数字传递给 printf 时,它会将其解释为有符号的,从而正确地将其转换回 -12。

The correct syntax to print a unsigned in print f is "%u" - try this and see what it does!

在 print f 中打印无符号的正确语法是“%u”——试试这个,看看它做了什么!

回答by mouviciel

The assignment of a negative value to an unsigned int does not compute the absolute value of the negative: it interprets as an unsigned int the binary representation of the negative value, i.e., 4294967284 (2^32 - 12).

将负值分配给 unsigned int 不计算负值的绝对值:它将负值的二进制表示解释为 unsigned int,即 4294967284 (2^32 - 12)。

printf("%d") performs the opposite interpretation. This is why your program displays -12.

printf("%d") 执行相反的解释。这就是您的程序显示 -12 的原因。

回答by trevor

int and unsigned int are used to allocate a number of bytes to store a value nothing more.

int 和 unsigned int 用于分配一些字节来存储一个值。

The compiler should give warnings about signed mismatching but it really does not affect the bits in the memory that represent the value -12.

编译器应该给出有关有符号不匹配的警告,但它确实不会影响内存中代表值 -12 的位。

%x, %d, %u etc tells the compiler how to interrupt a number of bits when you print them.

%x、%d、%u 等告诉编译器在打印时如何中断一些位。