![](/img/trans.png)
[英]Different behavior of double and int64_t conversion on new Apple silicon (arm64) vs. x86_64
[英]Implicit type conversion and different behavior between x64 and arm64
在 arm64 上测试我的软件时,我遇到了一个奇怪的问题。
我写了一些代码来重现这个问题:
char c;
int sum = 0;
for (int i = 0; i <= 255; i++)
{
c = i;
int a = c * 10;
sum += a;
std::cout << a << std::endl;
}
当我在 Windows(使用 Visual Studio 2017 构建)或 Ubuntu x64(gcc 9.3.0-17)上运行它时,我得到以下结果:
0
10
...
1260
1270
-1280
-1270
-20
-10
sum=-1280
如果我在 Ubuntu arm64 (gcc 9.3.0-17) 上运行相同的代码,我会得到不同的结果:
0
10
...
1260
1270
1280
1290
...
2540
2550
sum=326400
我不知道 arm64 上的 gcc 是否有一些额外的优化(使用 -O3),或者是否有一些我看不到的问题? 关于如何解决这个问题的任何想法?
char
数据类型可以是signed或unsigned 。 在前者的情况下(似乎是针对 x64 的情况), c = i
语句将导致for
循环的第129次迭代(有signed char
的最大值为 127)和它的值溢出正在分配的“环绕”为负值。
但是,当以 arm64 为目标时,您的编译器似乎使用unsigned char
类型(范围为0
到255
),因此该语句中没有溢出,并且算术“按预期”进行。
要确认(或以其他方式)上述诊断,只需检查不同构建环境中的CHAR_MAX
常量(在<climits>
头文件中定义)的值。
char
由标准签名。
然而,ARM 几十年前决定默认不签名。
就这么简单。
char
用 8 位表示,并有符号。 在第一位被解释为负数之后,您可以存储 0-127。 也许最好使用uint8_t
或类似的代替char
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.