use strict; use warnings; sub magnitude { my ($n, $p) = @_; $p ||= 16; # Num of significant digits. 16 max for doubles return 0 + ( sprintf('%.*e', $p-1, $n) =~ /e(.*)/ )[0]; } sub movement { my ($old, $new) = @_; my $m = magnitude($old); return 0 + sprintf '%.0f', ($new-$old) * 10**(4-$m); } printf("%+.0f\n", movement(@ARGV)); #### >perl movement.pl 1.0025 1.003 +5 >perl movement.pl 10.025 10.03 +5 #### >perl movement.pl 98000 99000 +1000 >perl movement.pl 99000 100000 +1000 >perl movement.pl 100000 99000 -100 >perl movement.pl 99000 98000 -1000