use strict; use warnings; my $lookup = create_lookup(); printf "%14d : %14d \n", $_, $lookup->($_) for (qw /24000 25000 51000 85000000 670000 260000000 78893999998 157788000001/); sub create_lookup { my %lookup_h = qw / 25000 2500 50000 5000 150000 12500 225000 25000 300000 37500 600000 60000 1200000 120000 3600000 300000 5400000 600000 10800000 900000 21600000 1800000 43200000 3600000 64800000 7200000 129600000 10800000 216000000 21600000 432000000 43200000 864000000 86400000 1728000000 172800000 3024000000 345600000 6048000000 604800000 12096000000 1209600000 31557600000 2629800000 63115200000 5259600000 78894000000 7889400000 157788000000 15778800000 /; my @keys = sort {$a <=> $b} keys %lookup_h; my $size = scalar @keys; my $ceil = $keys[-1]; my $ceil_val = = $lookup_h{$ceil}; return sub { my $v = shift; return $ceil_val if $v >= $ceil; return $lookup_h{$keys[0]} if $v < $keys[0]; my ($min, $max) = (0, $size); while (1) { my $mid = int (($min + $max)/2); return $lookup_h{$keys[$max]} if $max - $min <= 1; $min = $mid and next if $v > $keys[$mid]; $max = $mid; } } } #### $ perl lookup.pl 24000 : 2500 25000 : 5000 51000 : 12500 85000000 : 10800000 670000 : 120000 260000000 : 43200000 78893999998 : 7889400000 157788000001 : 15778800000