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