简体   繁体   中英

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

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.

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 .

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. (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; you need to also know the result.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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