x86|VS2022和浮点整型转换( 二 )


VS2019中的转换规则对于 VS2019 , 我们打算使所有 FP 到整数的转换与相应的英特尔架构转换指令兼容 。这允许在选择 /arch:AVX512 时使用 VCVTTSD2USI 和 VCVTTSS2USI 而不会改变行为 。但是 , 这种变化比我们预期的要困难一些 , 并且一些测试用例还没有完成 。它仅在选择 /arch:AVX512 时在 x64 上启用 。在 x86 上 , 选择 /arch:IA32 或 /arch:SSE 时未启用它 。此外 , 在 x86 上 , 从函数调用返回的浮点值的转换行为可以是任何一种方式 。虽然这仍然与标准 C++ 兼容 , 但这显然是不可取的 , 我们引入了 /fpcvt 选项以允许开发人员选择他们想要的行为 。
编译开关/fpcvt从VS2019 版本 v16.7 开始 , /fpcvt 编译选项控制浮点到无符号整数转换的结果 。有两个选择:/fpcvt:BC 指定向后兼容的 VS2017 行为 , 和 /fpcvt:IA 指定新的 AVX-512 指令行为 。此选项适用于 x86 或 x64 目标 , 无论是否指定 /arch:AVX512 都适用 。在 VS2022 中 , 默认值已更改为与 /fpcvt:BC 相同 , 但 /fpcvt:IA 选项仍可用于 x86 和 x64 。
用于转换的编译器内部函数使用/fpcvt编译开关 , 有如下几个问题:
> 它适用于所有已编译的转换 , 即使这不是最佳选择 。
> 它适用于可能已编写为预期其他行为的头文件和源代码模块 。
> /fpcvt 选项都不会生成饱和转换 。Saturation 提供与 Rust 和 WebAssembly 等语言的兼容性 , 以及针对 ARM 编译的代码 。
VS2022 提供了内部函数来解决这些问题 。这些标记和饱和转换函数在 IA 上完全定义 , 因此行为不会因编译设置或上下文而改变 。
除了这些函数之外 , 还有快速转换函数 , 它们尽可能快地执行有效转换 。与饱和转换和哨兵转换不同 , 它们没有完全定义 , 并且可能会根据目标平台、编译设置和上下文为无效转换生成不同的值或异常 。它们对于处理已经过范围检查的值或以永远不会导致无效转换的方式生成的值非常有用 。
具体请看下表:

/QIfirst不再支持VS2022的v17.0版本仍然支持 x86 上已弃用的 /QIfist 选项 , 但我们将在更新中将其删除 。此选项允许浮点到 int 转换根据当前舍入模式进行舍入(通常是舍入到最近的舍入 , 与偶数相关) , 而不是像标准 C++ 中指定的那样总是截断 。此选项支持在采用截断作为标准之前在 x86 上面编写的遗留代码 。它从未在其他目标平台上得到支持 , 并且在许多版本中都被标记为已弃用 。在转换为整数之前使用内部函数对浮点值进行舍入 , 因为这更清晰、更快且更易于移植 。
总结乖乖 , 想不到浮点转整型 , 还有这么多门道 。
原理小的就先跳过 , 还是走一步看一步吧 。
最后Microsoft Visual C++团队的博客是我非常喜欢的博客之一 , 里面有很多关于Visual C++的知识和最新开发进展 。 大浪淘沙 , 如果你对Visual C++这门古老的技术还是那么感兴趣 , 则可以经常去他们那(或者我这)逛逛 。
本文来自:《Microsoft Visual Studio 2022 and Floating-point to Integer Conversions》