I searched for (but didn't find) a way to get the human "how many?" function, so I wrote:

#!/usr/bin/perl # fuzzy-size.pl # = Copyright 2010 Xiong Changnian <xiong@sf-id.com> = # = Free Software = Artistic License 2.0 = NO WARRANTY = use strict; use warnings; use feature qw( say ); # "How many apples are in the box?" # This is an ordinary question asked by ordinary people every day. # It's not the same as "Count the apples in the box." # A rough estimate will be fine. # # fuzz() returns 0 for 0 and the exact number for 1, 2, or 3. # It returns 3 ("a few") for 4 also and 6 ("half dozen") for 5..7; # and so forth for increasing magnitudes. # fuzz() returns "the same" (negated) values for negative integers; # we sometimes ask "How many do we need" as well. # But fractions are ignored; you don't count broken apples. # my @raw = ( -768, -9, -3, -2, -1, -0.5, 0, 0.005, 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, 100, 768, 18433, 633999, ); my $in ; my $out ; foreach $in ( @raw ) { $out = fuzz( $in ); say $in, qq{\t}, $out; }; sub fuzz { my $in = int shift; # no floats here, move + along my $out ; return 0 if ( $in == 0 ); my $negative = ( $in < 0 ); # store algebraic sign $in = abs $in; $out = int sqrt exp ( (int log $in**2) + 0.7 ); if ( $negative ) { $out = 0 - $out; }; # restore sign return $out; }; __DATA__ Output: -768 -943 -9 -10 -3 -3 -2 -2 -1 -1 -0.5 0 0 0 0.005 0 0.5 0 1 1 2 2 3 3 4 3 5 6 6 6 7 6 8 10 9 10 10 10 11 10 12 10 13 17 14 17 15 17 16 17 17 17 18 17 19 17 20 17 21 28 23 28 100 127 768 943 18433 18958 633999 627814 __END__

Replies are listed 'Best First'.
Re: Fuzzy How-Many
by ambrus (Abbot) on Apr 29, 2010 at 09:44 UTC

    Here's my variant. It serves the same purpose, but gives rounder numbers for large inputs.

    sub fuzz { my $x = int($_[0]); 0 == $x and return 0; my $sgn = $x < 0 ? ($x = - $x, -1) : 1; my $ten = 0; while (10 <= $x) { $x = $x/10; $ten++; } my $y = $x <= 1.25 ? 1 : $x <= 2 ? 1.6 : $x <= 3.1 ? 2.5 : $x <= 5 ? 4 : $x <= 8 ? 6.3 : 10; $sgn * int(0.6 + $y * 10 ** $ten); }
Re: Fuzzy How-Many
by repellent (Priest) on May 09, 2010 at 20:43 UTC
    When I play the role of a human explaining a number, I tend to round up the absolute value at some fuzzy index of that number. After the round-up, anything that follows that index is zero-ed out.
    sub fuzz { my $n = shift(); return unless defined($n); my $neg = ($n < 0); ($n) = ($n =~ /(\d+)/); $n += 0; my ($c1, $c2) = ($n =~ /^(\d{0,2}\d{3})((?:\d{3})*)$/); return $neg ? -$n : $n unless defined($c1); my $c3 = substr($c1, -3, 2, ""); my $c4 = substr($c1, -1, 1, ""); my $n2 = $c1 . $c3; my $x1 = 100 - $c3; my $x2 = (10 - $c3 % 10) % 10; $n2 += $c1 ? ( ($x1 <= 30 && $c1 >= 10) ? $x1 : $x2 ? $x2 : $c4 ? 1 : 0 ) : ($c4 ? 1 : 0); $n2 .= 0 x (length($c2) + 1); return $neg ? -$n2 : $n2; }

    The tests explain better than words: