$opt{'value-format'} = $opt{units} && sub {
my $unit = int(
log(abs $_[0] || 1) / log(10)
- - 3 * ($_[0] < .9995) # shift to smaller unit if below 1
+ - 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}$/;
- sprintf('%3.*f%1s',
+ 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]
--- /dev/null
+ -10p ----------------------------=+|
+-200p ----------------------------=+|
+-3.0n ----------------------------=+|
+ -40n ----------------------------=+|
+-500n ----------------------------=+|
+-6.0μ ----------------------------=+|
+ -70μ ----------------------------=+|
+-800μ ----------------------------=+|
+-9.0m ----------------------------=+|
+-100m ----------------------------=+|
+-1.1 ----------------------------=+|
+ -12 ----------------------------=+|
+-130 ----------------------------=+|
+-1.4k ----------------------------=+|
+ -15k ----------------------------=+|
+-160k ----------------------------=+|
+-1.7M ----------------------------=+|
+ -18M ----------------------------=+|
+-190M ----------------------------
+-2.0G
+
+-999k - ----------------------------=+|
+-1.0M + ----------------------------=+|
+-1.0M ----------------------------=+|
+-1.0M - ----------------------------=+|
+-1.1M + ----------------------------=+|