Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl-删除不带指数值的尾随零_Perl - Fatal编程技术网

Perl-删除不带指数值的尾随零

Perl-删除不带指数值的尾随零,perl,Perl,我试图从十进制数中删除尾随的零 例如:如果输入数字是0.0002340000,我希望输出是0.000234 我使用的是sprintf(“%g”,$number),但这在大多数情况下都有效,只是有时它会将数字转换为带有E-的指数值。如何使其仅显示为完整的十进制数字?为了避免数字的科学表示法,请使用格式转换%f而不是%g解决方案比您想象的要简单 不要使用%g而是使用%f,这样会导致您正在寻找的行为%f将始终以“固定小数表示法”输出浮动小数 关于%g与%f的对比,文档说明了什么? 正如您在下表中可能

我试图从十进制数中删除尾随的零

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


我使用的是
sprintf(“%g”,$number)
,但这在大多数情况下都有效,只是有时它会将数字转换为带有E-的指数值。如何使其仅显示为完整的十进制数字?

为了避免数字的科学表示法,请使用格式转换
%f
而不是
%g

解决方案比您想象的要简单

不要使用
%g
而是使用
%f
,这样会导致您正在寻找的行为<代码>%f
将始终以“固定小数表示法”输出浮动小数


关于
%g
%f
的对比,文档说明了什么? 正如您在下表中可能注意到的那样,
%g
将导致与
%f
%e
相同的结果(如果适用)

Ff您可能希望强制使用固定十进制表示法,并使用适当的格式标识符,在本例中为
%f


TIMTOWTDI呢;我们不是在写perl吗? 是的,像往常一样,做这件事的方法不止一种

如果您只想从字符串中修剪后面的小数点零,可以使用如下正则表达式

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

$number # is now "12300.321"

请记住,perl中的浮点值没有尾随小数,除非您处理的是字符串。话虽如此,;字符串不是数字,即使它可以显式和隐式转换为一。

格式的全部要点是在合理时使用定点表示法,在定点不合理时使用指数表示法。因此,您需要知道要处理的值的范围

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

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

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

数字后面没有零。尾随零只能出现在以十进制表示数字(字符串)时。因此,第一步是将数字转换为字符串(如果尚未转换)

my $s = sprintf("%.10f", $n);
(解决方案是假设OP的输入是有效的,他的输入似乎有10位小数。如果你想显示更多的数字,请使用你想显示的小数位数,而不是10位。我认为这是显而易见的。如果你想像@asjo一样可笑,如果你想确保不显示双倍,请使用324位小数。)e任何您尚未失去的精度。)

然后可以删除尾随的零

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


懒惰的方法可能很简单:
$number=~s/0+$/
(用零代替尾随的零)。

简单的方法:

Original: 2.34e-007
New     : 0.000000234
您可能会有点作弊。添加1以避免数字变成科学符号。然后将数字作为字符串进行操作(从而使perl将其转换为字符串)


一种“适当”的方式:

Original: 2.34e-007
New     : 0.000000234
为了获得更“正确”的解决方案,计算要与
%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;
}

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

原件:

my$num=sprintf(“%.10f”,0.00023400001234);
打印(个);
#输出
0.0002340000
乘以:

my$num=sprintf(“%.10f”,0.00023400001234)*1;
打印(个);
#输出
0.000234

只有当值是字符串时,才可以有尾随的零。
您可以向其中添加0。它将转换为数值,不显示任何尾随的零。

当我尝试使用%f时,它将数字四舍五入到小数点后6位。在某些情况下,可能会有多达12位的小数点,我希望保留所有的小数点,然后您现在需要指定格式的宽度!这个问题似乎比看起来更复杂。@user333746
%f
的默认精度是小数点右侧的6位。您可以使用
%.nf
指定n位精度(例如,
%.10f
将给出10位精度)。您还可以使用sprintf的额外参数指定精度,如下所示:
sprintf(“%.*f”,$precision,$value)
。如果使用
%g
格式化,则不会有任何尾随零,因为它将以指数表示法显示;如果使用纯
%f
,则将在小数点后获得所有零,因为默认精度为6(正则表达式将去掉小数点后的所有零,留下
0.
;更完整的正则表达式也可能删除小数点:
s/\.?0+$/
)。是的,我想我知道会发生什么。问题是:提问者希望发生什么?因为我们没有被告知要格式化的值的范围,所以我们不能确切地说出什么是最好的。问题是要避免指数符号,所以%g对小数不起作用,这就是我问的原因。这就是为什么我说“%g”使用fixed或指数,如果您只想固定,使用“%f”…因此…我不确定您的抱怨是什么?如果您的回答不同,请继续这样做。如果浮点是
123000.0
,则上面的正则表达式将不会产生正确的行为!有关正确的操作方法,请参阅。嗯,“123000”。“可以说是删除了所有尾随零:-)真正的问题是变量是否是一个数字而不是一个字符串。OP想从十进制数中删除所有尾随零,这“可以说”意味着只有在
$s =~ s/0+\z// if $s =~ /\./;
$s =~ s/\.\z//;
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