在c++中将长双精度舍入为无符号长整型



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中。

最新更新