当前位置: 技术问答>linux和unix
类型转换的问题
来源: 互联网 发布时间:2016-12-28
本文导语: #include int main(int argc, char *argv[]) { long n1, n2; long r; unsigned short s1, s2; s1 = 100; s2 = 10; n1 = 0; n2 = 1; r = 1000 * (n2 - ...
#include
int
main(int argc, char *argv[])
{
long n1, n2;
long r;
unsigned short s1, s2;
s1 = 100;
s2 = 10;
n1 = 0;
n2 = 1;
r = 1000 * (n2 - n1) + (s2 - s1);
printf("%ldn", r);
return 0;
}
正常应该输出910
为什么在AIX下,用xlc编译,输出结果是4294968206
是不是xlc的bug?或者是未定义行为?
|
按照xlc的结果,s2 - s1他给转成了unsigned long,再和1000 * (n2 - n1)相加……
正常的“短类型转长类型”的规则,不同类型相加会按照长类型取值
所以,现在的关键就是1000 * (n2 - n1)的结果,编译器把他认成什么类型,xlc认成unsigned long,VC认成long
这个还真不好说是bug……
正常的“短类型转长类型”的规则,不同类型相加会按照长类型取值
所以,现在的关键就是1000 * (n2 - n1)的结果,编译器把他认成什么类型,xlc认成unsigned long,VC认成long
这个还真不好说是bug……
|
(s2 - s1)
一般的编译器都是把中间计算结果转化为int形,上面的中间结果就是-10.
但是这个编译器是按照参与计算的s2、s1,转化为unsigned shot形。
所以,中间计算加强制转化最安全。
r = (int)(1000 * (int)(n2 - n1)) + (int)(s2 - s1)
一般的编译器都是把中间计算结果转化为int形,上面的中间结果就是-10.
但是这个编译器是按照参与计算的s2、s1,转化为unsigned shot形。
所以,中间计算加强制转化最安全。
r = (int)(1000 * (int)(n2 - n1)) + (int)(s2 - s1)
|
学习了!
|
有道理,可能是编译器的原因
|
有道理,编译器中间进行了类型转换导致
|
类型的byte存储结构和方式取决于compiler
|
应该是类型转换导致的.
这种情况反汇编看看会比较清楚.
这种情况反汇编看看会比较清楚.
|
unsigned short转换为long的过程中出问题了
|
学习学习,没用过xlc。。
|
我觉得不是参数转换问题,而是执行顺序问题,你用括号将s2 - s1括起来,那么他就会先计算s2 -s1,得到一个极大的数,然后再将这个极大的数进行数据类型转换,自然就得到一个极大地值。
你如果把括号去了,应该就不会这样了。
你如果把括号去了,应该就不会这样了。
|
无符号的unsinged short 想减变成一个大数
|
unsigned short s1, s2;
估计是这里的问题。你这两个是无符号类型的,它就比其他的类型少了一半。比如int的范围[-32767-32767]。你可以做个测试啊,把unsigned short改成与其他类型一致的long,这样就可以试一下了
估计是这里的问题。你这两个是无符号类型的,它就比其他的类型少了一半。比如int的范围[-32767-32767]。你可以做个测试啊,把unsigned short改成与其他类型一致的long,这样就可以试一下了
|
无符号整数运算出负数也没啥,二进制还是-90的.
问题主要在于Long和unsigned short运算时,到底是无符号转有符号还是有符号转无符号.
问题主要在于Long和unsigned short运算时,到底是无符号转有符号还是有符号转无符号.
|
learn
|
好像C语言标准并没用规定中间值是无符号还是有符号。这个好像是编译器的事情,但是绝大多数编译器都会按照有符号处理。
我以前遇到过这样的问题,char形的变量在有的编译器认为是有符号的,有的是无符号的。
这样的结果会导致这样的问题:
char ch = 0x80;
int x = ch;
有的编译器会认为x是正数(0x80),有的编译器会把x认为是个负数。
所以,变量之间的赋值强制转换还是非常必要的。---大部分情况下,没人会处理这些warning的。