C++中是否有将long double
转换为unsigned long long
的内置函数?
根据这个答案,看起来double
不足以表示一些unsigned long long
值。如果long double
也不够,请纠正我。
我还知道有一个名为roundl
的函数,它对long double
进行舍入,但再次返回long double
。
另一个函数lround
只能返回long
,并且适用于较小范围的值。
给定一个long double
,如何将其四舍五入到类型为unsigned long long
的最近整数?
谢谢。
相关问题
从无符号长整型转换为双整型,反之亦然会更改值
TL;DR使用std::llroundl
,假设初始值小于2^64
。如果它更大,那么它无论如何都不适合,所以由你决定如何处理它。
IEEE 754浮点数可以表示直到某一点的任何整数。如果你把一个整数转换成这样的数字,然后再转换回相同的整数类型,只要整数不大于可表示的极限,你就会得到完全相同的值。
对于双精度数字,正如这个答案中所解释的,这就是2^53
,它对于所有32位整数来说都足够大。我们可以对四精度数字应用相同的通用公式,得到2^113
,它对所有64位整数都足够大。
因此,如果实现中的long double
是一个四精度数字,而unsigned long long
是一个64位整数,那么您可以安全地执行往返:
unsigned long long i = /* a very big value */;
long double d = i; // safe because it's a widening conversion
assert(static_cast<unsigned long long>(d) == i); // should pass
现在,如果long double
中没有一个整数,那么当然会有一些损失,因为这个分数必须被切割。如果你先对数字进行四舍五入,你会得到一个整数,这个整数是可表示的,所以没有损失(假设它不大于2^113
(,但当然,你最终得到的数字与四舍五进前的数字不同。
long double d = /* a very big value */;
unsigned long long i = static_cast<unsigned long long>(std::roundl(d));
或者,您可以使用std::llroundl
:来完全避免强制转换
long double d = /* a very big value */;
unsigned long long i = std::llroundl(d);
尽管你需要小心负数(但这很容易事先检查(。
所有这些都假设您的long double
永远不会大于2^64
,但如果是,那么您无论如何都无法将其放入unsigned long long
中。