简体   繁体   English

Perl:哪些浮点运算是无损的?

[英]Perl: Which floating point operations are lossless?

There are some great docs out there describing the nature of floating point numbers and why precision must necessarily be lost in some floating point operations. 有一些很棒的文档描述了浮点数的本质以及为什么必须在某些浮点运算中丢失精度。 Eg,: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html 例如: http//docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

I'm interested in understanding which floating point operations are lossless in terms of the precision of the underlying number. 我有兴趣了解哪些浮点运算在底层数字的精度方面是无损的。 For instance, 例如,

$x = 2.0/3.0; # this is an operation which will lose some precision

But will this lose precision? 但这会失去精确度吗?

$x = 473.25 / 1000000;

or this? 或这个?

$x = 0.3429 + 0.2939201;

What general rules of thumb can one use to know when precision will be lost and when it will be retained? 可以使用哪些一般经验法则来确定精度何时会丢失以及何时保留精度?

In general most operations will introduce some precision loss. 通常,大多数操作会引入一些精度损失。 The exceptions are values that are exactly representable in floating point (mantissa is expressible as a non-repeating binary). 例外是在浮点中可精确表示的值(尾数可表示为非重复二进制)。 When applying arithmetic, both operands and the result would have to be expressible without precision loss. 当应用算术时,两个操作数和结果必须是可表达的而没有精度损失。

You can construct arbitrary examples that have no precision loss, but the number of such examples is small compared with the domain. 您可以构造没有精度损失的任意示例,但与域相比,此类示例的数量较少。 For example: 例如:

1.0f / 8.0f = 0.125f

Put another way, the mantissa must be expressible as A/B where B is a power of 2, and (as pointed out by @ysth) both A and B are smaller than some upper bound which is dictated by the total number of bits available for the mantissa in the representation. 换句话说,尾数必须表示为A/B ,其中B是2的幂,并且(如@ysth所指出的) AB都小于某个上限,这是由可用的总位数决定的对于表示中的尾数。

Your question makes a big assumption. 你的问题是一个很大的假设。

The issue isn't whether certain operations are lossless, it's whether storing numbers in floating point at all will be without loss. 问题不在于某些操作是否无损,而是以浮点存储数字是否会毫无损失。 For example, take this number from your example: 例如,从您的示例中获取此数字:

$x = .3429;
sprintf "%.20f", $x;

Outputs: 输出:

0.34289999999999998000

So to answer your question, some operations might be lossless in specific cases. 因此,要回答您的问题,某些操作在特定情况下可能无损。 However, it depends on both the original numbers and the result, so should never be counted upon. 但是,它取决于原始数字和结果,所以永远不要指望它。

For more information, read perlnumber . 有关更多信息,请阅读perlnumber

I don't think you'll find any useful rules of thumb. 我认为你不会找到任何有用的经验法则。 Generally speaking, precision will not be lost if both the following are true: 一般来说,如果以下两种情况都属实,精度不会丢失:

  • Each operand has an exact representation in floating point 每个操作数都有一个浮点精确表示
  • The (mathematical) result has an exact representation in floating point (数学)结果具有浮点的精确表示

In your second example, 473.25 / 1000000, each operand has an exact floating point representation, but the quotient does not. 在第二个示例中,473.25 / 1000000,每个操作数都有一个精确的浮点表示,但商不具有。 (Any rational number that has a factor of 5 in the denominator has a repeating expansion in base 2 and hence no exact representation in floating point.) The above rules are not particularly useful because you cannot tell ahead of time whether the result is going to be exact just by looking at the operands; (分母中任何因子为5的有理数在基数2中都有重复扩展,因此在浮点上没有精确表示。)上述规则不是特别有用,因为你无法提前告诉结果是否会通过观察操作数来确切地说; you need to also know the result. 你还需要知道结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM