我正在尝试从十进制数字中删除尾随零。
例如:如果输入的数字是0.0002340000,我希望输出为0.000234
我正在使用sprintf("%g",$number)
,但这大部分都有效,除非有时它会将数字转换为带有E-的指数值。如何才能将其显示为完整的十进制数?
答案 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
。
%% 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
是的,一如既往,有多种方法可以做到。
如果您只想从字符串修剪尾随小数点零,则可以使用正则表达式,如下所示。
$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。它将被转换为数值,不显示任何尾随零。