我对 rounding a float
/double
变量到最接近的整数有/有一些困惑。在谷歌搜索时,我遇到了 rounding 的 https://en.cppreference.com/w/cpp/numeric/math/round cppreference 页面。在该页面上,它说:
float round ( float arg ); // (1)
float roundf( float arg ); // (2)
double round ( double arg ); // (3)
long double round ( long double arg ); // (4)
double round ( IntegralType arg ); // (5)
在这里,我不明白为什么返回value是类型float
,double
,或long double
?例如,如果我有一个变量 float x
和 2.5 <= x < 3.5
,那么其四舍五入的 value 就是 3
。这可以仅使用 int
来表示,对吗?那么,为什么 std::round
的返回 value 类型不是 int
(或 long double
的 long it
)?
在该页面上,它还说:
1-5) 计算与 arg 最接近的整数 value(浮点格式),rounding 距离零的一半,无论当前的 rounding 模式如何。
那么,“整数 value 到 arg(浮点格式)”到底是什么意思?
为了理解这个std::round
,我做了一个小实验:
int main(int argc, char const *argv[]) {
float var = 3.14;
int rounded_var_int = std::round(var);
float rounded_var_float = std::round(var);
std::cout << rounded_var_int << ", " << rounded_var_float << std::endl; // 3, 3
return 0;
}
然而,这让我更加困惑,因为一切都运行得很好。
所以,最后一个问题:
在上面的代码中, int rounded_var_int = std::round(var)
很好,或者我需要将它显式转换为 int
例如int rounded_var_int = static_cast<int>(std::round(var))
以避免任何潜在的错误?
回答1
为什么 std::round 的返回 value 类型不是整数?
因为浮点类型的可表示范围通常超出基本整数类型的范围,因此这些整数类型不能代表所有潜在的返回values。
除了超出整数类型范围的有限舍入 values 之外,其他有问题的 values 是无穷大、非数字 values、负零,它们会原封不动地返回。
四舍五入的 value 是 3。这可以只用一个 int 来表示,对吧?
这个 value 可以用 int
表示。但是能够代表一个或一些 values 是不够的。返回类型应该能够表示所有四舍五入的 values。而这通常用 int
无法实现。
在上面的代码中,
int rounded_var_int = std::round(var)
很好,或者我需要将它显式转换为 int,例如int rounded_var_int = static_cast<int>(std::round(var))
以避免任何潜在的错误?
浮点类型可以隐式转换为整数类型。隐式转换的结果与静态转换的结果相同。
这是一个狭窄的转换。从某种意义上说,如果浮点 value 超出可表示范围,则无论是隐式转换还是显式转换都是安全的,那么程序的行为是未定义的。这两种转换都是安全的,如果 value 是可表示的,那么 value 将在转换过程中保持不变。