奇怪行为C#与Python字节操作

时间:2016-01-06 22:17:35

标签: c# python

为什么C#:

byte[] vals = new byte[] {223, 30, 244, 156};
int result = 0;
for(int i = 0; i <= 3; ++i) {
  result <<= 8;
  result |= vals[i];
}
print("RESULT: " + result);

收益率:

RESULT: -551619428

虽然Python:

vals = array.array('B', [223, 30, 244, 156])
result = 0
for val in vals:
  result <<= 8
  result |= val
print 'RESULT: %s' % result

收率:

RESULT: 3743347868

虽然......抛出数组值:

[37, 120, 244, 167]

两种语言产生:

RESULT: 628683943

编辑:我没有在原始问题中包含这个,但我的实际目标是让Python在这种情况下表现得像C#。根据下面的答案,我看到我需要强制Python端的int溢出。

这似乎有效:

import numpy
result = numpy.int32(result)

3 个答案:

答案 0 :(得分:6)

在C#int中是带符号的32位整数。 int的最大值为2147483647 - 低于3743347868。您执行的操作会导致溢出,从而导致负值。

如果将result的类型更改为unsigned int(uint)或64位整数(long),则C#代码将提供与Python相同的结果:

byte[] vals = new byte[] {223, 30, 244, 156};
uint result = 0;
for(int i = 0; i <= 3; ++i) {
  result <<= 8;
  result |= vals[i];
}

答案 1 :(得分:3)

这个计算器可以说明一切。

enter image description here

左侧显示int 64中的结果(当使用unsigned int 32时,它将显示相同的结果)。而右侧使用int 32.因为顶部位用于负数,它将显示不同的数字。

请注意,所有位都相同。这就是有符号和无符号整数之间的区别。

答案 2 :(得分:2)

似乎C#使用32位int,因此3743347868是-551619428 unsigned int 应该使C#在这个问题上表现得更像python。