Perl - remove trailing zeros without an exponential value

I am trying to remove trailing zeros from decimal numbers.

For example, if the input number is 0,0002340000, I would like the output to be 0,000234

I use sprintf("%g",$number) , but this works for the most part, except sometimes it converts a number to an exponential value using E-. How can I only display it as a full decimal number?

+4
source share
6 answers

Numbers do not have trailing zeros. Trailing zeros can occur only after the number is represented in the decimal string. So, the first step is to convert the number to a string, if it has not already been.

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

(The solution should work with OP inputs, and its inputs seem to have 10 decimal places. If you want more digits to appear, use the number of decimal places you want to display instead of 10. I thought it was obvious . If you want to be ridiculous, like @asjo, use 324 decimal places to double, if you want not to lose accuracy, which you have not lost.)

Then you can remove trailing zeros.

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

or

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

or

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

To avoid scientific notation for numbers, use %f format conversion instead of %g .

+1
source

The solution is simpler than you think.

Instead of using %g use %f and this will lead to the behavior you are looking for. %f always outputs your floating decimal to "fixed decimal notation".


What does the documentation say about %g vs %f ?

As you can see in the table below, %g will lead to the same thing as %f or %e (if necessary).

Ff, you want to force use fixed decimal notation, use the appropriate format identifier, which in this case is %f .

sprintf - perldoc.perl.org

  %% a percent sign %ca character with the given number %sa string %da signed integer, in decimal %u an unsigned integer, in decimal %o an unsigned integer, in octal %x an unsigned integer, in hexadecimal %ea floating-point number, in scientific notation %fa floating-point number, in fixed decimal notation %ga floating-point number, in %e or %f notation 

What about TIMTOWTDI; don't we write perl?

Yes, as always, there are several ways to do this.

If you want to trim null zero decimal points from a string , you can use regex like below.

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

Remember that floating point values ​​in perl do not have trailing commas, unless you are dealing with a string. With that said; a string is not a number, although it can be explicitly and implicitly converted to one.

+1
source

The lazy way can be simple: $number=~s/0+$// (replace trailing zeros with nothing).

+1
source

The whole point of the %g format is to use fixed-point notation when it is reasonable, and use exponential notation when the fixed point is not reasonable. So, you need to know the range of values ​​that you will be dealing with.

Obviously, you could write a regular expression to process the string from sprintf() later, removing trailing zeros:

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

If you always want a fixed-point number, use ' %f ', possibly with the number of decimal places you want; you may need to remove trailing zeros. If you always want a sample record, use ' %e '.

0
source

A simple way:

You can cheat a little. Add 1 to avoid a number falling into scientific notation. Then manipulate the number as a string (thereby converting perl to a string).

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

"The right way:

For a more “correct” solution, counting the number of decimal places for use with %f would be optimal. It turned out that the correct number of decimal points is harder than you might think. Here is an attempt:

 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 eg 0.01 $dec += length $num; return $dec; } 

Output:

 Original: 2.34e-007 New : 0.000000234 
0
source

Source: https://habr.com/ru/post/1388531/


All Articles