舍入用于int - >浮动 - > int往返转换

时间:2009-12-10 19:29:39

标签: c++ c floating-point rounding

我正在为数据库引擎编写一组数值类型转换函数,我担心将大整数浮点值转换为更精确的整数类型的行为。

例如,将32位int转换为32位单精度浮点数。浮点数的23位有效数产生大约7个十进制数字的精度,因此转换任何大于7位数的int将导致精度损失(这很好并且预期)。但是,当您将这样的float转换回int时,最终会得到低位数字的二进制表示的工件:

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
    int a = 2147483000;
    cout << a << endl;
    float f = (float)a;
    cout << setprecision(10) << f << endl;
    int b = (int)f;
    cout << b << endl;

    return 0;
}

打印:

2147483000
2147483008
2147483008

尾随008超出了float的精度,因此似乎不希望保留在int中,因为在数据库应用程序中,用户主要关注十进制表示,而尾随0用于表示无关紧要的数字。

所以我的问题是:是否有任何众所周知的现有系统在浮点数中执行十进制有效数字舍入 - &gt; int(或double - > long long)转换,是否有任何众所周知的高效算法?

(注意:我知道有些系统有十进制浮点类型,例如IEEE 754-2008定义的那些。但是,它们没有主流硬件支持,也没有内置到C / C ++中我可能想在路上支持他们,但我仍然需要直观地处理二进制浮点数。)

2 个答案:

答案 0 :(得分:1)

std::numeric_limits<float>::digits10说你只能得到6个精确数字的浮点数。

为您的语言,处理器和数据分发选择一种有效的算法calculate-the-decimal-length-of-an-integer(或here)。然后减去digits10所说的精确位数,以获得要剔除的位数。使用它作为索引来查找10的幂以用作模数。等

一个问题:假设您将浮点数转换为小数并执行此类舍入或截断。然后将“已调整”的小数转换为浮点数并使用相同的舍入/截断方案返回到小数。你得到相同的十进制值吗?希望是的。

这不是你想要的,但可能是有趣的阅读:A Proposal to add a max significant decimal digits value to the C++ Standard Library Numeric limits

答案 1 :(得分:0)

当然,如果以二进制(1111111111111111111110110000000)或十六进制(0b0x7FFFFD80)写入,则2147483008具有尾随零。最“正确”的做法是跟踪任何这些形式中无关紧要的数字。

或者,你可以在从float转换为它之后,在int中的前七个有效数字之后将所有数字归零(理想情况是通过舍入),因为float包含大约七位有效数字。

相关问题