从double转换为float时检测精度损失

10

我正在编写一段代码,需要将双精度数转换为单精度数。我使用boost::numeric_cast来执行此转换,以便在溢出/下溢时发出警告。但是,我还想知道这个转换是否导致了精度损失。

例如

    double source =  1988.1012;
    float dest = numeric_cast<float>(source);

产生值为1988.1的dest。

是否有任何可用的方法可以检测这种精度丢失/四舍五入?


7
在这种情况下,将会始终存在“精度损失”。 - Paul R
4个回答

13

您可以将浮点数转换回double类型,并将其与原始值进行比较 - 这应该可以给您一个关于是否存在精度损失的公正指示。


4
比公正更好。它将精确地告诉你是否丢失了任何信息。 - Stephen Canon

11
float dest = numeric_cast<float>(source);
double residual = source - numeric_cast<double>(dest);
因此,residual 包含了你正在寻找的“损失”。

1

查看这些有关单精度双精度浮点数的文章。首先,浮点数的指数有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 + ...)组成。因此,除非你能以确切的方式相加这些分数得到精确的数字,否则无法编码精确的值。这是很少见的。因此,几乎总会存在精度损失。

1
我可以建议指向经常提到的http://docs.sun.com/source/806-3568/ncg_goldberg.html吗?(我没有足够的声望来自己完成) - Alexandre C.

1

根据Dave的回答,您将会有一定程度的精度损失。然而,如果您想要关注量化并在超过某个数字时引发异常,您将需要打开浮点数本身并解析出尾数和指数,然后进行一些分析以确定是否超出了您的容差。

但好消息是,它通常是标准的IEEE浮点数!:-)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接