将最小值整数转换为无符号长整型

Convert min value integer to unsigned long

本文关键字:无符号 长整型 转换 最小值 整数      更新时间:2023-10-16

我正在尝试将整数的最小值转换为无符号长整型,如下所示:

-2147483648 to 2147483648存储在整数变量中的第一个值,第二个是我试图使我的无符号长变量采用的值。

所以我知道如何将整数的最小值转换为无符号 int-2147483648因为它出现在下面的主要内容中:

int main()
{
int d = -2147483648;
unsigned int u = (d * -1);              
printf("%un", u);                             //the output is "2147483648"
}

但是当我尝试对转换为无符号长整型做同样的事情时,我的输出变成了我设备上的最大无符号长整型值的值18446744071562067968

int main()
{
int d = -2147483648;
unsigned long ul = (d * -1);              
printf("%lun", ul);                             //the output is "18446744071562067968"
}

我搜索了一些关于数据类型及其范围的信息,我看到无符号长整型的范围是
0 to 18446744073709551615,我认为当我们将整数的最小值乘以-1时,它不会改变,因为整数的最大值是2147483647,所以它保持-2147483648,当我把它交给不包含该值的无符号长整型时, 它成为其自身范围的最大值18446744073709551615.

所以我尝试将-2147483648 * -1的值存储在long int变量中,其范围为

-9223372036854775808 to 9223372036854775807,所以它可以存储2147483648的值。

int main()
{
int d = -2147483648;
long int l = d;                 // l now contains -2147483648
l *= -1;                        // now it becomes 2147483648
unsigned long ul = l;           // now we managed to store 2147483648 in unsigned long variable
printf("%ldn", ul)             //the output is "2147483648"
}

在这里我的问题解决了,但这次我想像下面这样用铸造来做:

int main()
{
int d = -2147483648;
unsigned long ul = (long)(d * -1);          
printf("%lun", ul)             //the output is "18446744071562067968" :(
}

但是当我尝试以另一种方式投射它时unsigned long ul = -(long)(d);出现了想要的输出2147483648

所以我的问题是第一种铸造方法和第二种铸造方法有什么区别,为什么它只使用第二种方式?

您的情况是未定义的行为,因为d * -12147483648会导致 int 溢出。

为了避免这种情况,您需要在操作之前将 int 值转换为长整型或无符号长整型值(就像您在另一个示例中所做的那样(。

这是因为如果操作是在 2 int 之间完成的,则在 int 变量中解决并导致溢出,之后在赋值过程中它将被强制转换为无符号长整型。

您需要通过早期演员阵容来防止这种情况。

所以正如 razor 在前面的回答中所说,我需要对整数d进行早期强制转换,然后将其乘以-1,正如你这样看到的:

unsigned long ul = -(long)(d);或这样unsigned long ul = ((long)d) * -1;它们都是有效的,并且不会导致任何未定义的行为。

但是以这种转换方式unsigned long ul = (long)(d * -1);结果是未定义的行为,为什么?让我们一步一步地解释它。

我们有(d * -1),它们都是整数,所以当我将-2147483648乘以-1时,所需的预期输出是2147483648,但不幸的是整数在其范围内没有这样的值,它会导致未定义的行为,大多数情况下该值不会改变,即使将其乘以-1也会保持-2147483648

然后我们强制转换未更改的值,该值-2147483648长整数,它将保留它,因为它在其范围内,因此该值现在仍然-2147483648,之后我们将此值存储在无符号长整数中,这里它将是一个未定义的行为,因为我们在无符号值中放置了一个负数。

因此,为了避免这个问题,我们要做的就是将-2147483648转换为long,然后将其乘以-1==>((long)d) * -1,因为long可以存储正值2147483648因为它的范围。

然后我们可以将其存储在无符号的长整型中,而不会面临任何未定义的行为。

这是一个有关数据类型范围的更多详细信息的网站:

https://www.tutorialspoint.com/cprogramming/c_data_types.htm