Perl - 删除没有指数值的尾随零

时间:2011-12-29 23:10:06

标签: perl

我正在尝试从十进制数字中删除尾随零。

例如:如果输入的数字是0.0002340000,我希望输出为0.000234

我正在使用sprintf("%g",$number),但这大部分都有效,除非有时它会将数字转换为带有E-的指数值。如何才能将其显示为完整的十进制数?

8 个答案:

答案 0 :(得分:3)

数字没有尾随零。仅当您表示十进制数字(字符串)时,才会出现尾随零。因此,第一步是将数字转换为字符串,如果它还没有。

my $s = sprintf("%.10f", $n);

(解决方案是假设使用OP的输入,他的输入似乎有10个小数位。如果你想要更多的数字出现,使用你想要出现的小数位数而不是10.我想这个很明显。如果你想像@asjo一样荒谬,如果你想确保不丢失任何你没有丢失的精度,那么为双打使用324位小数。)

然后你可以删除尾随零。

$s =~ s/0+\z// if $s =~ /\./;
$s =~ s/\.\z//;

$s =~ s/\..*?\K0+\z//;
$s =~ s/\.\z//;

$s =~ s/\.(?:|.*[^0]\K)0*\z//;

答案 1 :(得分:1)

为避免数字的科学记数法,请使用格式转换%f代替%g

答案 2 :(得分:1)

解决方案比您想象的要容易。

而不是使用%g使用%f,它将导致您正在寻找的行为。 %f将始终以“固定十进制表示法”输出浮动小数。


文档对%g vs %f的说法是什么?

正如您在下表%g中所注意到的那样,%f %e(适当时)会产生相同的效果。

如果您想强制使用固定十进制表示法,请使用相应的格式标识符,在本例中为%f

sprintf - perldoc.perl.org

   %%    a percent sign
   %c    a character with the given number
   %s    a string
   %d    a signed integer, in decimal
   %u    an unsigned integer, in decimal
   %o    an unsigned integer, in octal
   %x    an unsigned integer, in hexadecimal
   %e    a floating-point number, in scientific notation
   %f    a floating-point number, in fixed decimal notation
   %g    a floating-point number, in %e or %f notation

TIMTOWTDI怎么样;我们不是在写perl吗?

是的,一如既往,有多种方法可以做到。

如果您只想从字符串修剪尾随小数点零,则可以使用正则表达式,如下所示。

$number =  "123000.321000";
$number =~ s/(\.\d+?)0+$/$1/;

$number # is now "12300.321"

请记住,perl中的浮点值没有尾随小数,除非您正在处理字符串。照这样说;字符串不是数字,即使它可以显式地和隐式地转换为数字。

答案 3 :(得分:1)

一种懒惰的方式可能只是:$number=~s/0+$//(用空格替换尾随零)。

答案 4 :(得分:0)

%g格式的重点是在合理时使用固定点表示法,并在固定点不合理时使用指数表示法。因此,您需要知道您将要处理的值的范围。

显然,您可以编写正则表达式来对sprintf()中的字符串进行后处理,删除尾随的零:

my $str = sprintf("%g", $number);
$str =~ s/0+$//;

如果您总是想要一个固定的点数,请使用“%f”,可能还有您想要的小数位数;您可能仍需要删除尾随零。如果您始终需要指数表示法,请使用“%e”。

答案 5 :(得分:0)

一种简单的方法:

你可以作弊。添加1以避免数字分为科学记数法。然后将数字作为字符串操作(从而使perl将其转换为字符串)。

$n++; 
$n =~ s/^(\d+)(?=\.)/$1 - 1/e;
print $n;

“正确”的方式:

对于更“正确”的解决方案,计算与%f一起使用的小数位数是最佳的。事实证明,获得正确的小数点数比人们想象的要复杂。这是一次尝试:

use strict;
use warnings;
use v5.10;

my $n = 0.000000234;
say    "Original: $n";
my $l = getlen($n);
printf "New     : %.${l}f\n", $n;

sub getlen {
    my $num = shift;
    my $dec = 0;
    return 0 unless $num;    # no 0 values allowed
    return 0 if $num >= 1;   # values above 1 don't need this computation
    while ($num < 1) {
        $num *= 10;
        $dec++;
    }
    $num =~ s/\d+\.?//;     # must have \.? to accommodate e.g. 0.01
    $dec += length $num;
    return $dec;
}

<强>输出:

Original: 2.34e-007
New     : 0.000000234

答案 6 :(得分:0)

最简单的方法可能是乘以 1。

原文:

my $num = sprintf("%.10f", 0.000234000001234);
print($num);

#output
0.0002340000

乘法:

my $num = sprintf("%.10f", 0.000234000001234) * 1;
print($num);

#output
0.000234

答案 7 :(得分:0)

该值只有在它是字符串时才可以有尾随零。 你可以给它加0。它将被转换为数值,不显示任何尾随零。