unit rounding corner case
authorMischa POSLAWSKY <perl@shiar.org>
Mon, 31 Oct 2022 16:08:57 +0000 (17:08 +0100)
committerMischa POSLAWSKY <perl@shiar.org>
Tue, 1 Nov 2022 03:14:54 +0000 (04:14 +0100)
Earlier commits did not account for odd unit offsets with one less digit
like 9950 rounding to 10.0k (or 9.9k with the previous fix) instead of 10k.

barcat
t/t1402-rounded.in
t/t1402-rounded_-H_-w1.out

diff --git a/barcat b/barcat
index aa9a88e528aa67c5b1c652c6c35a4eb372882f4b..ab5c023398e94300363dfd1a23d991782b8d91e0 100755 (executable)
--- a/barcat
+++ b/barcat
@@ -112,18 +112,21 @@ $opt{input} = (@ARGV && $ARGV[0] =~ m/\A[-0-9]/) ? \@ARGV : undef
 $opt{'sum-format'} = sub { sprintf '%.8g', $_[0] };
 $opt{'calc-format'} = sub { sprintf '%*.*f', 0, 2, $_[0] };
 $opt{'value-format'} = $opt{units} && sub {
-       my $unit = int(
+       my $unit = (
                log(abs $_[0] || 1) / log(10)
                - 3 * (abs($_[0]) < .9995)   # shift to smaller unit if below 1
-               - log(.9995) / log(10)  # 3 digits rounding up
                + 1e-15  # float imprecision
        );
-       my $float = $_[0] !~ /^0*[-0-9]{1,3}$/;
+       my $decimal = ($unit % 3) == ($unit < 0);
+       $unit -= log($decimal ? .995 : .9995) / log(10);  # rounded
+       $decimal = ($unit % 3) == ($unit < 0);
+       $decimal &&= $_[0] !~ /^-?0*[0-9]{1,3}$/;  # integer 0..999
        sprintf('%*.*f%1s',
                3 + ($_[0] < 0), # digits plus optional negative sign
-               $float && ($unit % 3) == ($unit < 0),  # tenths
-               $_[0] / 1000 ** int($unit/3),   # number
-               $#{$opt{units}} * 1.5 < abs $unit ? "e$unit" : $opt{units}->[$unit/3]
+               $decimal,  # tenths
+               $_[0] / 1000 ** int($unit/3),  # number
+               $#{$opt{units}} * 1.5 < abs $unit ? sprintf('e%d', $unit) :
+                       $opt{units}->[$unit/3]  # suffix
        );
 };
 
index edaab9fa2bba6dbbba7d67cc2cc52f17b05a3a65..6140548637c72537df24dc00ec5e3a0681f90904 100644 (file)
@@ -9,6 +9,15 @@
 .0009995 +
 .001
 
+9949 -
+9950 +
+9994 +
+9995 +
+10000
+99499 -
+99500 +
+100000
+
 999.49 -
 999.50 +
 1000
index cd9ae5eeb05107e903f9e794b52ec36c4f2e2989..a09503f630334a65ce8acd8c64a528076299105b 100644 (file)
@@ -9,6 +9,15 @@
 1.0m +  
 1.0m    
 
+9.9k -  
+ 10k +  
+ 10k +  
+ 10k +  
+ 10k    
+ 99k -  
+100k +  
+100k    
+
 999  -  
 1.0k +  
 1.0k