__int64的奇怪列表输出

时间:2013-05-28 17:15:00

标签: c++ c int64

我遇到__int64%I64u的问题。或者可能是我的配方有问题。我想模仿下面的输出。但是在某些订单项中会发生奇怪的事情。我无法理解发生了什么,因为其他人打印得很好。

注意:这些列表的主要来源是二进制原始数据。所以我从十六进制中获取它并尝试在__int64中转换它。我的列表包含120个订单项,这些订单项在73行之前输出良好,但在74行失败且预期值为2276812558且显示为18446744071691396878。从第74行到第120行,结果为intermittent。其他人都没事,其他线路都失败了。

有谁帮忙?

来源:

74  2276812558     <-- expected output
...
110 88343310421     <-- expected output
111 101677534814    <-- expected output
112 116372862414    
113 132547934111    <-- expected output
114 150330130721
115 169856101434    <-- expected output
116 193905458276    
117 220253625665    
118 249089120712    <-- expected output
119 280613529205    
120 315042247217

这是我的代码:

    longint =  (__int64)((col[3] << 24) | (col[2] << 16) | (col[1] << 8)) | ((col[0]) | (__int64)((col[7] << 56) | (col[6] << 48) | (col[5] << 40) | (col[4] << 32)) << 32);
sprintf(longintbuf,"%I64u", longint );

.OUTPUT GENERATED

74  18446744071691396878    <-- err
...
110 18446744071858548821    <-- err
111 18446744072307871326    <-- err
112 116372862414    
113 18446744073113499551    <-- err
114 150330130721    
115 18446744071766961210    <-- err
116 193905458276    
117 220253625665    
118 18446744073690569160    <-- err
119 280613529205    
120 315042247217

1 个答案:

答案 0 :(得分:1)

如果col不是64位类型的数组,则您的移位会导致未定义的行为。转移之前的演员:

(__int64)col[7] << 56

如果移位会导致符号更改,这也是未定义的行为,因此在使用签名类型时要小心(就像你一样)。

来自C11 6.5.7按位移位运算符(强调我的):

  

对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。 如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义。

     

E1 << E2 的结果是 E1 左移 E2 位位置;腾出的位用零填充。 ... 如果 E1 具有签名类型和非负值,并且 E1×2 E2 可以在结果类型中表示,那么这就是结果值;否则,行为未定义。