c - ARM 上的 double2unsigned(vcvt 指令)

标签 c assembly arm

<分区>

我有简单的代码。在 x86(visual studio)上,最后两行代码的 res 是相同的。

short res;
double CONST = 32768.0
double d=-0.85;
res = ( unsigned short)( d * CONST );
res = ( short)( d * CONST );

在 ARM(GCC) 上转换为无符号得到不正确的结果。

short dres;
double CONST = 32768.0
double d=-0.85;
dres = ( unsigned short )( d * CONST );
//007db5c4:   vldr d17, [pc, #76]
//007db5c8:   vldr d16, [r11, #-20]
//007db5cc:   vmul.f64 d7, d17, d16 ;d7=={u8 = {51, 51, 51, 51, 51, 51, 219, 192}, u16 = {13107, 13107, 13107, 49371}, u32 = {858993459, 3235590963}, u64 = 13896757370177139507, f32 = {4.17232506e-08, -6.8499999}, f64 = -27852.799999999999}
//007db5d0:   vcvt.u32.f64 s15, d7 ;s15==0 !!!!!!!!!!!!!!!!!!!!! incorrect
//007db5d4:   vstr s15, [r11, #-48]
//007db5d8:   ldrh r3, [r11, #-48]
//007db5dc:   uxth r3, r3
//007db5e0:   strh r3, [r11, #-6]
dres = ( short )( d * CONST );
//007db5e4:   vldr d17, [pc, #44]
//007db5e8:   vldr d16, [r11, #-20]
//007db5ec:   vmul.f64 d16, d17, d16
//007db5f0:   vcvt.s32.f64 s15, d16 ;s15==-nan(0x7f9334)
//007db5f4:   vmov r3, s15
//007db5f8:   strh r3, [r11, #-6]

这是正确的行为还是错误?

最佳答案

这不是编译器错误。

对于 16 位 short

的行为
res = ( unsigned short)( d * CONST );

未定义,因为您溢出了一个signed类型一个float的转换值-1 或更少到 unsigned 整数类型。这会将整个程序置于未定义状态。

关于c - ARM 上的 double2unsigned(vcvt 指令),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50927701/

相关文章:

c++ - 什么更有效率?使用 pow 平方还是仅将其与自身相乘?

C/C++ - 使用 mmap 的内存映射文件

assembly - x86 AT&T 语法汇编的注释语法

c - 大端字节数组到 C、arm 中的小端结构元素

android - Flutter 大 apk 大小并针对不同的 ABI 发布

c - C中基于数组的堆栈实现

c - 重新分配() : invalid next size in C

计算全局偏移表在arm文字池中的地址

assembly - MIPS bne beq 计算机组织与设计

c - 需要使用C将int转换为字符串