我遇到__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
答案 0 :(得分:1)
如果col
不是64位类型的数组,则您的移位会导致未定义的行为。转移之前的演员:
(__int64)col[7] << 56
如果移位会导致符号更改,这也是未定义的行为,因此在使用签名类型时要小心(就像你一样)。
来自C11 6.5.7按位移位运算符(强调我的):
对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。 如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义。
E1 << E2
的结果是E1
左移E2
位位置;腾出的位用零填充。 ... 如果E1
具有签名类型和非负值,并且E1
×2 E2 可以在结果类型中表示,那么这就是结果值;否则,行为未定义。