c++ - 在 C++(和 C)中进行类型转换时出现明显的不一致
问题描述
任何人都可以在这里解释输出吗?我一直试图理解为什么类型转换文字的结果与此代码中的类型转换变量不同。
#include <iostream>
#include <cstdint>
using namespace std;
int main()
{
double intermediate;
intermediate = -1.0;
cout << "intermediate = " << intermediate << endl;
cout << "uint64_t(intermediate) = " << uint64_t(intermediate) << endl;
cout << "uint64_t((double)(-1)) = " << uint64_t((double)(-1)) << endl;
return 0;
}
我得到的输出是:
intermediate = -1
uint64_t(intermediate) = 18446744073709551615
uint64_t((double)(-1)) = 0
解决方案
您正在执行从浮点类型到整数类型的超出范围的转换。
由于 double 值-1.0
不能放入 a 中uint64_t
,因此这被认为是超出范围的转换。这种转换会调用未定义的行为。这意味着,除其他外,两次转换的尝试不需要产生相同的结果。
请注意,这不同于有符号整数到无符号整数的转换,这在所有情况下都有明确定义。
这是由C++17 标准的 7.10p1 规定的:
浮点类型的纯右值可以转换为整数类型的纯右值。转换截断;也就是说,小数部分被丢弃。如果截断的值不能在目标类型中表示,则行为未定义。
C11 标准的第 6.3.1.4p1 节有类似的语言:
当实浮点类型的有限值转换为除 以外的整数类型
_Bool
时,小数部分被丢弃(即,该值被截断为 0)。如果整数部分的值不能用整数类型表示,则行为未定义。61)...
61) 将整数类型的值转换为无符号类型时执行的求余运算不需要在将实浮点类型的值转换为无符号类型时执行。因此,可移植实浮点值的范围是 (−1,Utype_MAX+1)
要获得一致的结果,您首先需要转换为有符号整数类型,然后是无符号类型。
cout << "uint64_t(intermediate) = " <<
static_cast<uint64_t>(static_cast<int>(intermediate)) << endl;
对于 C:
printf("uint64_t(intermediate) = %llu\n", (uint64_t)(int)intermediate);
推荐阅读
- xml - XSLT 1.0:同时复制结构和子结构
- javascript - 如何解决在苹果手机上的 chrome 中无法正确显示图像
- php - 登录时出错:此存储库只能附加到 ORM 可排序侦听器
- android - 如何使用android中的数据绑定在布局编辑器中隐藏视图
- html - 使用带有自定义 CSS 的 type="search" 时,'x' 未显示在 Firefox 输入中
- java - Drools:为什么一个撤回的事实仍然出现在收集中
- sql-server - SSRS 报告未显示来自数据库的图像
- javascript - 如何用 JS 将 HTML 重写为 HTML?
- db2 - 如何在 DB2 9.5 和 11.5 中将 CLOB 强制转换为 INTEGER?
- delphi - 将字符串转换为 Cardinal / UInt32