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?hp=736f0a09c45e37cfef46689640d7fcac30ff9eee 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