提问人:yeputons 提问时间:10/14/2023 最后编辑:yeputons 更新时间:10/14/2023 访问量:89
Visual Studio 2022 如何处理双倍到长整型超范围转换?
How does Visual Studio 2022 handle double-to-long long out-of-range conversion?
问:
请考虑以下使用 Visual Studio 2022 编译的 C++ 代码:
#include <iostream>
#include <intrin.h>
int main() {
std::cout << _cvt_dtoll_sent(1e31) << "\n";
std::cout << _cvt_dtoll_sat(1e31) << "\n";
std::cout << _cvt_dtoll_fast(1e31) << "\n";
std::cout << (long long)1e31 << "\n";
}
在 x86 中,它打印:
-9223372036854775808
9223372036854775807
4016683251292700672
-4571153621781053440
在 x64 中,它打印:
-9223372036854775808
9223372036854775807
-9223372036854775808
-4571153621781053440
该程序使用四种不同的方式转换为 .由于不适合(有符号的 64 位整数),因此行为在 C++ 标准下未定义。但是,VS2022 有一个默认为 /fpcvt:BC
的特殊选项,引用:double
long long
1e31
long long
/fpcvt:BC 选项还使到有符号类型的转换在源无效时返回最小可能值
因此,我希望返回哨兵值 ,就像 一样。但是,它不仅不会返回哨兵,而且与转换的“饱和”或“快速”版本不一致。为什么?(long long)1e31
-9223372036854775808
_cvt_dtoll_sent
答: 暂无答案
评论
/fpcvt:BC
_cvt_dtoll_fast
(long long)1e31
to_long_long(1e31)
auto to_long_long(double x) -> long long { return static_cast<long long>(x); }