我真的需要这个解决方法来保持数字输出格式吗 在 perl 中改变小数字?
for ( 77777, 10, -15, 132, 66, 444.33, 0.0002 ) {
my $x = $_ / 1000 / 1000;
$x = sprintf "%.12f", $x; # Workaround: to guard against exponential notation
$x =~ s/0+$//; # Workaround: to clean up from previous line
print "$_ mm is $x km\n";
}
注意这是一个更一般的情况 在 perl 中打印 .00001 的解决方法
#!/usr/bin/perl
# Such a big problem to make perl print numbers consistently, as it
# decides when it wants to use scientific notation "without asking."
#
# Here are some "no trailing zeros and no scientific notation"
# solutions, all without using "printf"! (But be my guest and make
# your own printf solutions.)
#
use strict;
use warnings q(all);
for (qw/0.00001 0.0001 -0.00007 -0.50001 -6.00001 9/) {
print "\n";
print "Had: $_\n";
my $t = $_ + 0;
print "Got: $t\n";
next unless $t =~ /e/;
print "FixA: ", $t < 0 ? "-" : "", 0, substr( 1 + abs $t, 1 ), "\n";
my $k = $t;
$k =~ s/(\d+)e-(\d+)/"0." . (0 x ($2 - 1)) . $1/e;
print "FixB: $k\n";
$t =~ /^(-?)(\d+)e-(\d+)$/ or die "Uh oh";
print "FixC: ", $1 . "0." . ( 0 x ( $3 - 1 ) ) . $2, "\n";
}
# Once again it is safe to live next to the equator or prime meridian
# without your kid's geocaching club membership card having their
# coordinates in a format that they cannot yet understand, or with
# ugly trailing zeros. Same goes for city workers reading street lamp
# or manhole data sheets. P.S., Not very tested so don't launch any
# ICBMs with it.
use POSIX qw( isinf isnan );
# Works for any IEEE double-precision floating-point
# number including +Inf, -Inf and NaN values.
# The precision is measured in significant digits.
# If missing, undef or zero, no rounding is performed.
sub to_decimal_form {
my $n = shift;
my $precision = shift || 751;
return "0" if !$n;
return $n > 0 ? "Inf" : "-Inf" if isinf( $n );
return "NaN" if isnan( $n );
my $s = sprintf( "%.*e", $precision-1, $n );
my ( $sign, $digits, $e ) = $s =~ /^(-?)([^e]*)e(.*)/
or die( "Unexpected format <$s>" );
$digits =~ s/\.//;
$digits =~ s/0*\z//;
$e += length( $& ) - $precision;
if ( $e >= 0 ) {
$digits .= "0" x $e;
} else {
my $z = -$e - length( $digits ) - 1;
if ( $z >= 0 ) {
$digits = "0." . ( "0" x $z ) . $digits;
} else {
substr( $digits, -$z, 0, "." );
}
}
return $sign . $digits;
}