From: Mischa POSLAWSKY Date: Mon, 31 Oct 2022 16:08:57 +0000 (+0100) Subject: unit rounding corner case X-Git-Tag: v1.08~5 X-Git-Url: http://git.shiar.nl/barcat.git/commitdiff_plain/7234e799b9983646e36ea2d4c7735807120f5bcf unit rounding corner case 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. --- diff --git a/barcat b/barcat index aa9a88e..ab5c023 100755 --- 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 ); }; diff --git a/t/t1402-rounded.in b/t/t1402-rounded.in index edaab9f..6140548 100644 --- a/t/t1402-rounded.in +++ b/t/t1402-rounded.in @@ -9,6 +9,15 @@ .0009995 + .001 +9949 - +9950 + +9994 + +9995 + +10000 +99499 - +99500 + +100000 + 999.49 - 999.50 + 1000 diff --git a/t/t1402-rounded_-H_-w1.out b/t/t1402-rounded_-H_-w1.out index cd9ae5e..a09503f 100644 --- a/t/t1402-rounded_-H_-w1.out +++ b/t/t1402-rounded_-H_-w1.out @@ -9,6 +9,15 @@ 1.0m + 1.0m +9.9k - + 10k + + 10k + + 10k + + 10k + 99k - +100k + +100k + 999 - 1.0k + 1.0k