如何强制 perl 以与其他数字相同的格式打印小数字?

问题描述 投票:0回答:2

我真的需要这个解决方法来保持数字输出格式吗 在 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 的解决方法

perl printf precision
2个回答
1
投票
#!/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.

0
投票
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;
}
© www.soinside.com 2019 - 2024. All rights reserved.