我正在编写一段代码,我必须在其中将双精度值转换为浮点值。我正在使用 boost::numeric_cast 进行此转换,这将提醒我任何溢出/下溢。但是我也有兴趣知道这种转换是否会导致一些精度损失。
例如
double source = 1988.1012;
float dest = numeric_cast<float>(source);
生成 dest,其值为 1988.1
有什么方法可以检测到这种精度损失/舍入
我正在编写一段代码,我必须在其中将双精度值转换为浮点值。我正在使用 boost::numeric_cast 进行此转换,这将提醒我任何溢出/下溢。但是我也有兴趣知道这种转换是否会导致一些精度损失。
例如
double source = 1988.1012;
float dest = numeric_cast<float>(source);
生成 dest,其值为 1988.1
有什么方法可以检测到这种精度损失/舍入
您可以将浮点数转换回双精度并将该双精度与原始双精度进行比较 - 这应该可以为您提供一个关于是否存在精度损失的公平指示。
float dest = numeric_cast<float>(source);
double residual = source - numeric_cast<double>(dest);
因此,residual
包含您正在寻找的“损失”。
查看这些文章以了解单精度和双精度浮点数。首先,浮点数有 8 位用于指数,而 11 位用于双精度。因此,任何大于 10^127 或小于 10^-126 的量级都将成为您提到的溢出。对于浮点数,数字的实际数字为 23 位,而双精度数为 52 位。所以很明显,双精度数比浮点数多得多。
假设您有一个数字:1.1123。这个数字实际上可能不会被编码为 1.1123,因为浮点数中的数字实际上是用来作为分数相加的。例如,如果尾数中的位是 11001,那么该值将由 1(隐式)+ 1 * 1/2 + 1 * 1/4 + 0 * 1/8 + 0 * 1/16 + 1 * 形成1/32 + 0 * (64 + 128 + ...)。因此,除非您可以将这些分数相加,否则无法对确切的值进行编码,使其成为确切的数字。这是罕见的。因此,几乎总是会有精度损失。
根据戴夫的回答,您将有一定程度的精度损失。但是,如果您想专注于量化它并在超过某个数字时引发异常,您将不得不打开浮点数本身并解析尾数和指数,然后进行一些分析以确定您是否'已经超出了你的承受能力。
但是,好消息是,它通常是标准的 IEEE 浮点浮点数。:-)