签署双重签名到未签名的字节:ARM64与Win64

signed double to unsigned byte: ARM64 versus Win64

本文关键字:ARM64 Win64 字节 签署      更新时间:2023-10-16

出于某些遗产原因,我的代码对双重签名的字节进行了双重命名,我们看到了两个平台之间的差异。没有做 - "不要尝试将签名的值塞入无符号值中;不要尝试在整数中填充双重值",还有其他可以做的事情吗?

unsigned char newR1 = -40.16;

newr1的值是Windows上的216(正如我们从长期以来所期望的那样);但是在ARM64上是0。

胜利:

00007FF75E388818 cvttsd2si eax,mmword ptr [R] 
00007FF75E38881D mov byte ptr [newR1],al

在ARM64

00007FF6F9E800DC ldr d16,[sp,#0x38 |#0x38 ] 
00007FF6F9E800E0 fcvtzu w8,d16 
00007FF6F9E800E4 uxtb w8,w8 
00007FF6F9E800E8 strb w8,[sp,#0x43 |#0x43 ]

也会尝试这些,但只是想要其他一些意见

unsigned char newR1 = -40.16;
unsigned char newR2 = (int)-40.16;
unsigned char newR3 = (unsigned char)-40.16;
unsigned char newR4 = static_cast<int>(-40.16);

或可能是

int i = -40.16;
unsigned char c = i;

C标准所说的内容(C 中有类似的文本):

当真实浮动类型的有限值转换为整数 除_bool以外的其他类型,分数部分被丢弃(即 值将其截断为零)。如果整体部分的价值 不能用整数类型表示,行为是不确定的。

因此,从doubleunsigned char的单个铸件中,在-40.16中获得216,已经是UB。实际上,在这种情况下获得任何结果是UB。这就是为什么编译器可以自由生产任何东西而不是您想要的216。

您可能想做两个演员:

(unsigned char)(int)-40.16

再次,第一个演员(to int)仍受到我引用的上述限制。