[英]What happens when I assign long int to int in C?
In a recent homework assignment I've been told to use long
variable to store a result, since it may be a big number. 在最近的家庭作业中,我被告知使用
long
变量来存储结果,因为它可能是一个很大的数字。
I decided to check will it really matter for me, on my system (intel core i5/64-bit windows 7/gnu gcc compiler) and found out that the following code: 我决定检查它对我来说真的很重要,在我的系统上(intel core i5 / 64-bit windows 7 / gnu gcc编译器)并发现以下代码:
printf("sizeof(char) => %d\n", sizeof(char));
printf("sizeof(short) => %d\n", sizeof(short));
printf("sizeof(short int) => %d\n", sizeof(short int));
printf("sizeof(int) => %d\n", sizeof(int));
printf("sizeof(long) => %d\n", sizeof(long));
printf("sizeof(long int) => %d\n", sizeof(long int));
printf("sizeof(long long) => %d\n", sizeof(long long));
printf("sizeof(long long int) => %d\n", sizeof(long long int));
produces the following output: 产生以下输出:
sizeof(char) => 1
sizeof(short) => 2
sizeof(short int) => 2
sizeof(int) => 4
sizeof(long) => 4
sizeof(long int) => 4
sizeof(long long) => 8
sizeof(long long int) => 8
In other words, on my system, int
and long
are the same, and whatever will be too big for int
to hold, will be too big for long
to hold as well. 换句话说,在我的系统上,
int
和long
是相同的,并且对于int
任何太大都不能保持,也不会long
持有。
The homework assignment itself is not the issue here. 家庭作业本身不是问题。 I wonder how, on a system where
int < long
, should I assign an int
to long? 我想知道在一个
int < long
的系统上,我应该如何为long分配一个int
?
I'm aware to the fact that there are numerous closely related questions on this subject, but I feel that the answers within these do not provide me with the complete understanding of what will or may happen in the process. 我知道一个事实,即存在 有 许多 密切 相关的关于这个问题的问题,但我觉得在这些问题的答案没有给我提供什么将会或可能在这个过程中发生了全面的了解。
Basically I'm trying to figure out the following: 基本上我想弄清楚以下内容:
long
to int
before the assignment, or long
为int
,或者 long
is not a different data type, but merely a modifier, long
不是一个不同的数据类型,而只是一个修饰符, long > int
? long > int
系统上会发生什么? Will the result be undefined (or unpredictable) or it will cause the extra parts of the variable to be omitted? long
to int
works in C? long
到int
的转换如何在C中工作? long
to int
works in C when I don't use casting? long
到int
的赋值如何在C中起作用? The language guarantees that int
is at least 16 bits, long
is at least 32 bits, and long
can represent at least all the values that int
can represent. 该语言保证
int
至少为16位, long
至少为32位, long
可以至少表示int
可以表示的所有值。
If you assign a long
value to an int
object, it will be implicitly converted. 如果为
int
对象分配long
值,则会隐式转换它。 There's no need for an explicit cast; 没有必要进行明确的演员表演; it would merely specify the same conversion that's going to happen anyway.
它只会指定将要发生的相同转换。
On your system, where int
and long
happen to have the same size and range, the conversion is trivial; 在你的系统上,
int
和long
恰好具有相同的大小和范围,转换是微不足道的; it simply copies the value. 它只是复制价值。
On a system where long
is wider than int
, if the value won't fit in an int
, then the result of the conversion is implementation-defined. 在
long
比int
宽的系统上,如果该值不适合int
,则转换的结果是实现定义的。 (Or, starting in C99, it can raise an implementation-defined signal, but I don't know of any compilers that actually do that.) What typically happens is that the high-order bits are discarded, but you shouldn't depend on that. (或者,从C99开始,它可以引发实现定义的信号,但我不知道任何编译器实际上是这样做的。) 通常发生的是高位比特被丢弃,但你不应该依赖在那。 (The rules are different for unsigned types; the result of converting a signed or unsigned integer to an unsigned type is well defined.)
(对于无符号类型,规则是不同的;将有符号或无符号整数转换为无符号类型的结果已经明确定义。)
If you need to safely assign a long
value to an int
object, you can check that it will fit before doing the assignment: 如果需要为
int
对象安全地分配long
值,可以在执行赋值之前检查它是否合适:
#include <limits.h> /* for INT_MIN, INT_MAX */
/* ... */
int i;
long li = /* whatever */
if (li >= INT_MIN && li <= INT_MAX) {
i = li;
}
else {
/* do something else? */
}
The details of "something else" are going to depend on what you want to do. “别的东西”的细节将取决于你想做什么。
One correction: int
and long
are always distinct types, even if they happen to have the same size and representation. 一个更正:
int
和long
总是不同的类型,即使它们碰巧具有相同的大小和表示。 Arithmetic types are freely convertible, so this often doesn't make any difference, but for example int*
and long*
are distinct and incompatible types; 算术类型可以自由转换,因此这通常没有任何区别,但是例如
int*
和long*
是不同且不兼容的类型; you can't assign a long*
to an int*
, or vice versa, without an explicit (and potentially dangerous) cast. 如果没有明确的(也可能是危险的)强制转换,你不能将
long*
赋给int*
,反之亦然。
And if you find yourself needing to convert a long
value to int
, the first thing you should do is reconsider your code's design. 如果您发现自己需要将
long
值转换为int
,那么您应该做的第一件事就是重新考虑代码的设计。 Sometimes such conversions are necessary, but more often they're a sign that the int
to which you're assigning should have been defined as a long
in the first place. 有时候这种转换是必要的,但更常见的是,它们表明你所分配的
int
应该首先被定义为long
。
A long
can always represent all values of int
. long
总是可以表示int
所有值。 If the value at hand can be represented by the type of the variable you assign to, then the value is preserved. 如果手头的值可以由您指定的变量的类型表示,则保留该值。
If it can't be represented, then for signed destination type the result is formally unspecified, while for unsigned destination type it is specified as the original value modulo 2 n , where n is the number of bits in the value representation (which is not necessarily all the bits in the destination). 如果无法表示,则对于签名目标类型,结果是正式未指定的,而对于无符号目标类型,它被指定为模2 n的原始值,其中n是值表示中的位数(不是必然是目的地的所有比特)。
In practice, on modern machines you get wrapping also for signed types. 实际上,在现代机器上,您也可以为签名类型进行包装。
That's because modern machines use two's complement form to represent signed integers, without any bits used to denote "invalid value" or such – ie, all bits used for value representation. 这是因为现代机器使用二进制补码形式来表示有符号整数,而没有任何位用于表示“无效值”等 - 即用于表示值的所有位。
With n bits value representation any integer value is x is mapped to x +K*2 n with the integer constant K chosen such that the result is in the range where half of the possible values are negative. 对于n位值表示,任何整数值x被映射到x + K * 2 n ,其中选择的整数常数K使得结果处于可能值的一半为负的范围内。
Thus, for example, with 32-bit int
the value -7 is represented as bitpattern number -7+2 32 = 2 32 -7, so that if you display the number that the bitpattern stands for as unsigned integer, you get a pretty large number. 因此,例如,使用32位
int
,值-7表示为位模式编号-7 + 2 32 = 2 32 -7,因此如果您将位模式代表的数字显示为无符号整数,则会得到一个漂亮的大数字。
The reason that this is called two's complement is because it makes sense for the binary numeral system, the base two numeral system. 这被称为二进制补码的原因是因为它对二进制数字系统有意义,即基本两位数系统。 For the binary numeral system there's also a ones' (note the placement of the apostrophe) complement.
对于二进制数字系统,还有一个'(注意撇号的位置)补码。 Similarly, for the decimal numberal system there's ten's complement and niners' complement.
类似地,对于十进制数字系统,有十个补码和niners补码。 With 4 digit ten's complement representation you would represent -7 as 10000-7 = 9993. That's all, really.
使用4位十进制补码表示,您将代表-7为10000-7 = 9993.这就是全部,真的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.