#! perl -slw use strict; sub log10{ log( $_[0] ) / log( 10 ) } sub ticks { my( $start, $end, $n ) = @_; $n ||= 10; my $range = $end - $start; $range += $range / $n; my $interval = $range / $n; $interval = 10**int( log10( $interval ) ); $interval *= 10 while ( $range / $interval ) > ( $n * 2 ); $interval /= 2 while ( $range / $interval ) < ( $n / 2 ); $start = int( $start / $interval ) * $interval; my @ticks; while( $start < ( $end + $interval ) ) { push @ticks, $start; $start += $interval; } return @ticks; } for my $range ( [0,9], [0.123,8.673], [0.022, 0.086], [1_123_345_456, 1_124_246_357.5], [1_123_345_456, 1_123_346_357.5], [ 0.00011, 0.00041], ) { for my $n ( 0, 4, 5, 8 , 10, 15, 16, 20, 21 ) { my @ticks = ticks( @$range, $n ); printf "from:%12.12g to %12.12g by:%2u -> [%2u][ %s ]\n", @$range, $n, scalar( @ticks ), join ' ', map{ my $s = sprintf( "%.8g", $_ ); $s =~ s[e([+-])0*([1-9]+)]['e' . ($1 eq '-' ? '-' : '') . $2]e; $s; } @ticks; } }