Why is Perl inconsistent with sprintf rounding?

前端 未结 2 2036
执笔经年
执笔经年 2021-02-20 02:20

Here is a Perl script:

#!/usr/bin/perl

use strict;
use warnings;
use feature \'say\';

my @numbers = qw(
    0.254
    0.255
    0.256
);

foreach my $number (@         


        
2条回答
  •  萌比男神i
    2021-02-20 02:48

    Perl uses the underlying C library for formatting. What this library does may vary from platform to platform. Even POSIX says "The low-order digit shall be rounded in an implementation-defined manner."

    In glibc, which arguably is used by the majority of perl binaries out there, the behavior you see will be affected by a couple of things:

    First, as pointed out in another answer, the value you think is being rounded may not be exactly representable in floating point, and which way the rounding goes will be determined by if it is the next higher or lower representable number.

    Second, even if the value is exactly representable as halfway between two possible roundings, glibc will use banker's rounding. That is, it will round to an even digit. So sprintf '%.1g', .25 will produce .2, but sprintf '%.1g', .75 will produce .8.

    The quote from the Perl Cookbook is just plain wrong.

提交回复
热议问题