To register for an Internet.com membership to receive newsletters and white papers, use the Register button ABOVE.
To participate in the message forums BELOW, click here
PHPBuilder.com  
 

 

Go Back   PHPBuilder.com > PHP Help > Code Critique

Code Critique Having someone critique your code is always a great way to hone the skills. Stop in and post your code to see what your peers may have done differently.

Reply
 
Thread Tools Rating: Thread Rating: 6 votes, 4.83 average. Display Modes
Old 12-22-2003, 08:00 AM   #1
Weedpacket
Custom User Title™
 
Weedpacket's Avatar
 
Join Date: Aug 2002
Location: Rapid Offensive Unit "Foreign Object Damage"
Posts: 19,137
Converting numbers to their names

Dunno if I should put this here or in the "Code Share" thread. I put it here because it can be knocked into practical use by having a few bits taken out. Ah well, BuzzLY can move it there if he wants.

Okay. I must be in holiday mode. Last night I flipped through Conway & Guy's The Book of Numbers, and noted they gave a table for the construction of "zillion" names - you know, when you have to come up with a new word ending with "illion" to deal with some big number. You start with "million", "billion", "trillion", but how many people are able to continue? Unabridged dictionaries might take you up as far as the twentieth zillion name - vigintillion - but conventional construction actually works up as far as the 999th zillion. Conway and Guy's table is implemented in the function zillion(), which includes the rules for inserting extra letters as needed to glue the various syllables together.

I thought I'd implement it. Then I went to bed. This evening I thought "okay, I've got it sussed" and wrote the attached.

To go beyond the 999th zillion (which happens to be "novenonagintanonagentillion") Conway & Guy mention a construction by some bloke named Allan Wechsler. That is also implemented below (in the function wechsler(), would you believe).

What the authors didn't mention was Donald Knuth's "yllion" nomenclature, which he spun off as an amusement in a paper on representing arbitrary integers with prefix-free codes. You'll notice that there's a function knuth().... Combining knuth() with wechsler() was my own idea: I'm not fantastically certain there's much call for "myllibyllinyllion" in everyday life, but it's nice to know it's there.

This code implements three nomenclatures. The third is Knuth's. The first two are, respectively, American (the default) and European.

The European is the original, developed by Nicholas Chuquet, who coined the words "million", "billion", ..., "nonillion" and described their use in the late fifteenth century. However, a buggy implementation started being distributed in the mid-seventeenth century, which managed to get itself exported to the United States, which uses it to this day.

I mention this because (a) it explains the use of the constants NUM2NAME_AMERICAN, NUM2NAME_EUROPEAN, NUM2NAME_KNUTH, and (b) this code is probably way too armour-plated if you're planning on using anything like it in real life. Like I said: who needs "myllibyllinyllion"? (It's equal to ten to the power of a certain 301633-digit integer.) So one can, for instance, cut it down to American-only, or European-only. (In the former case, you'll want to go through triplets() and the end of num2name() itself and remove the insertion of "and": I've adopted the distinction that European nomenclature uses "and" while American nomenclature does not: Knuth's nomenclature doesn't either - 'cos Knuth himself doesn't.) You can also chop out the call to wechsler() if you're not going to be needing any zillions above "novenonagintanonagentillion", and for that matter, you can drop the entirety of the zillion() function from that point on if you're not planning on going as far as "one decillion": you only need "// The easy bit".

Sheez, my code is ugly. Good grief; and what with all my waffle it's too big to post inline.

(Edit: nonono: save the file, then upload it!)
Attached Files
File Type: txt num2name.txt (9.0 KB, 343 views)
__________________
On two occasions I have been asked [by Members of Parliament], "Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?" I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question.

Last edited by Weedpacket; 09-08-2004 at 08:28 AM.
Weedpacket is offline   Reply With Quote
Old 12-22-2003, 03:18 PM   #2
planetsim
code | beer > sleep
 
Join Date: Sep 2002
Location: aus
Posts: 4,826
Havent tested it yet but i guess someone hasnt got much to do at the moment.
__________________
Dont be lazy Search
And use the Manual
Webmobo - Open Source News Script | Portfolio / Blog | Against TCPA
planetsim is offline   Reply With Quote
Old 12-22-2003, 09:08 PM   #3
intenz
Xtreme Member
 
intenz's Avatar
 
Join Date: Aug 2001
Location: Reykjavik, Iceland
Posts: 506
Nice.
__________________
Curiosity killed the cat.
intenz is offline   Reply With Quote
Old 12-23-2003, 01:18 AM   #4
coditoergosum
PHP Addict
 
coditoergosum's Avatar
 
Join Date: Nov 2002
Location: Salt Lake City, Utah
Posts: 352
Whoa I'm dizzy after just reading the first 4 paragraphs.

Interesting idea though. Have you thought of any practical uses for it?
__________________
<? include("beer.php"); echo("Mmm"); ?>
http://gagon.net
coditoergosum is offline   Reply With Quote
Old 12-23-2003, 01:53 AM   #5
Weedpacket
Custom User Title™
 
Weedpacket's Avatar
 
Join Date: Aug 2002
Location: Rapid Offensive Unit "Foreign Object Damage"
Posts: 19,137
Quote:
Originally posted by coditoergosum
Have you thought of any practical uses for it?
Yeah; chop out any bits you don't need and you've got a decimal integer &rarr; English name converter that (I hope) can be used in a live environment; hence the splitting of each degree of complication into separate functions.

You probably don't need all 3 (three) nomenclatures, and you might never have to deal with numbers above 2^32-1 (four billion two hundred ninety-four million nine hundred sixty-seven thousand two hundred ninety-five), or even much beyond 1000 (one thousand) or so.

For example, allowing only numbers up to 999,999,999,999,999,999,999,999,999,999,999 (one decillion minus one) in American nomenclature, and inlining triplets() and zillion(), gives:

PHP Code:
function num2name($number)
{
    if(
$number==0) return 'zero';

    
// Break the number into triples (counting from the right)
    
$number = explode(' ',strrev(chunk_split(strrev($number),3,' ')));
    
array_shift($number);

    
// So that lower-placed triples in the number
    // are given lower indices in the array.
    // This means we can insert "million" "billion" etc. while counting
    // forward instead of backward.
    
$number = array_reverse($number);

    
// Turn '123' into 'one hundred and twenty three'
    
$digs = array('zero', 'one', 'two', 'three', 'four',
                
'five', 'six', 'seven', 'eight', 'nine');
    
$tens = array('zeroty', 'onety', 'twenty', 'thirty', 'forty',
                
'fifty', 'sixty', 'seventy', 'eighty', 'ninety');
    
$teens = array('ten', 'eleven', 'twelve', 'thirteen', 'fourteen',
                 
'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen');
    foreach(
$number as $i => $v)
    {
        
$num = str_pad($v, 3, '0', STR_PAD_LEFT);
        list(
$h,$t,$u) = sscanf($num, '%1d%1d%1d');
        
$name = '';
        if(
$h>0) $name = $digs[$h].' hundred '.$name;
        if(
$t == 1)
            
$name .= $teens[$u];
        else
        {
            if(
$t != 0)
                
$name .= $tens[$t].'-';
            
$name .= $digs[$u];
        }
        
$name = str_replace('zero','',str_replace('-zero','',$name));
        
$number[$i] = $name;
    }

    if(
count($number)>1)
    {
        if(
$number[1] != '')
            
$number[1] .= ' thousand '.$number[0];
        else
            
$number[1] = $number[0];
        unset(
$number[0]);
    }
    
// Tidy the array indices.
    
$number = array_values($number);

    
// Add zillion names
    
$count = count($number);
    if(
$count>10)
    {    
trigger_error('Number too large (>=10^'.(3*$i+3).')', E_USER_WARNING);
        return
false;
    }
    
// Chuquet's words
    
$i_below_10 = array('', 'million', 'billion','trillion',
        
'quadrillion','quintillion', 'sextillion',
        
'septillion', 'octillion','nonillion');
    for(
$i = 1; $i<$count; ++$i)
    {
        if(
$number[$i]=='') continue;
        
$zillion = $i_below_10[$i];
        
$number[$i] .= ' '.$zillion;
    }

    
// Back around the other way again
    
$number = array_reverse($number);

    
$number = join(' ',$number);

    
// Tidy up loose spaces.
    
$number = preg_replace('/ $/', '', preg_replace('/  +/',' ',$number));
    return
$number;
}
Which could do with better variable names, but I just shoved the functions in there without considering that.

Cutting it down even further; here's a version that only handles integers <one million (further simplifications are now possible, and left as exercises for the reader):
PHP Code:
function num2name($number)
{
    if(
$number==0) return 'zero';

    
// Break the number into triples (counting from the right)
    
$number = explode(' ',strrev(chunk_split(strrev($number),3,' ')));
    
array_shift($number);

    
// So that lower-placed triples in the number
    // are given lower indices in the array.
    // This means we can insert "million" "billion" etc. while counting
    // forward instead of backward.
    
$number = array_reverse($number);

    
// Turn '123' into 'one hundred and twenty three'
    
$digs = array('zero', 'one', 'two', 'three', 'four',
                
'five', 'six', 'seven', 'eight', 'nine');
    
$tens = array('zeroty', 'onety', 'twenty', 'thirty', 'forty',
                
'fifty', 'sixty', 'seventy', 'eighty', 'ninety');
    
$teens = array('ten', 'eleven', 'twelve', 'thirteen', 'fourteen',
                 
'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen');
    foreach(
$number as $i => $v)
    {
        
$num = str_pad($v, 3, '0', STR_PAD_LEFT);
        list(
$h,$t,$u) = sscanf($num, '%1d%1d%1d');
        
$name = '';
        if(
$h>0) $name = $digs[$h].' hundred '.$name;
        if(
$t == 1)
            
$name .= $teens[$u];
        else
        {
            if(
$t != 0)
                
$name .= $tens[$t].'-';
            
$name .= $digs[$u];
        }
        
$name = str_replace('zero','',str_replace('-zero','',$name));
        
$number[$i] = $name;
    }

    if(
count($number)>1)
    {
        if(
$number[1] != '')
            
$number[1] .= ' thousand '.$number[0];
        else
            
$number[1] = $number[0];
        unset(
$number[0]);
    }
    
// Tidy the array indices.
    
$number = array_values($number);

    
// Add zillion names
    
$count = count($number);
    if(
$count>1)
    {    
trigger_error('Number too large (>=10^6)', E_USER_WARNING);
        return
false;
    }

    
// Back around the other way again
    
$number = array_reverse($number);

    
$number = join(' ',$number);

    
// Tidy up loose spaces.
    
$number = preg_replace('/ $/', '', preg_replace('/  +/',' ',$number));
    return
$number;
}
__________________
On two occasions I have been asked [by Members of Parliament], "Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?" I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question.

Last edited by Weedpacket; 06-25-2004 at 04:24 AM.
Weedpacket is offline   Reply With Quote
Old 12-23-2003, 04:04 AM   #6
bad76
GuruMeditation #8401.0007
 
bad76's Avatar
 
Join Date: May 2003
Location: Italy
Posts: 1,213
Quote:
Originally posted by weedpacket
Yeah; chop out any bits you don't need and you've got a decimal integer-English name converter that (I hope) can be used in a live environment;
Not forgivening the lyric of "ten green bottle"...
__________________
It's statistically proven that anything can be proven by means of statistics...
bad76 is offline   Reply With Quote
Old 12-23-2003, 06:00 AM   #7
Weedpacket
Custom User Title™
 
Weedpacket's Avatar
 
Join Date: Aug 2002
Location: Rapid Offensive Unit "Foreign Object Damage"
Posts: 19,137
Quote:
Originally posted by bad76
Not forgivening the lyric of "ten green bottle"...
Except I'd much rather quote Douglas Adams if I can get away with it
__________________
On two occasions I have been asked [by Members of Parliament], "Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?" I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question.
Weedpacket is offline   Reply With Quote
Old 06-24-2004, 10:01 PM   #8
hodge
Member
 
Join Date: Jun 2004
Posts: 30
anyone have an example ????

just wondering of anyone has this working??
if so please post the link would like to see it in
action.
thanks
hodge
hodge is offline   Reply With Quote
Old 06-25-2004, 12:17 AM   #9
BuzzLY
2($infinity) && $beyond
 
BuzzLY's Avatar
 
Join Date: Nov 2002
Location: Star Command
Posts: 2,535
Well... the code is posted above. If you want to see a page with it implemented, then here you go.
__________________
New to the board? Check out the guidelines
| Color Picker | Blogification |
¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
With all its sham, drudgery, and broken dreams, it's still a beautiful world.
BuzzLY is offline   Reply With Quote
Old 06-25-2004, 12:35 AM   #10
hodge
Member
 
Join Date: Jun 2004
Posts: 30
well thats real cool but

so I get a page full of text hummm
not what I was looking for.
but here is the real deal on a
number to text function that is working real good.



I think this is more in line with what I was looking for, but thanks for the link nice effort to help someone out .
Hodge
hodge is offline   Reply With Quote
Old 06-25-2004, 01:02 AM   #11
BuzzLY
2($infinity) && $beyond
 
BuzzLY's Avatar
 
Join Date: Nov 2002
Location: Star Command
Posts: 2,535
Am I in a parallel universe?

Weekpacket's function does EXACTLY what you are looking for. And it works -- the link I gave is a demo of HIS function printing out a very large number.

What are you looking for? If you're looking for a page that demonstrates how to write out numbers, try this one on for size. Note that the number is passed in the URL, and you can set it to anything you want.

I'm quite confused. You asked me to give you a flower, I gave you a flower. Then you said, no, I didn't want a flower, I wanted a flower.

You want a utility that converts numbers to their text equivalent in PHP, right? Use Weed's code. If you are looking for a page that will do the conversion for you, then just use the one you linked us to. If you are looking for something else, I have NO idea what it is.

And telling me "good effort" might look like you are being grateful, but to me it came off sounding quite condescending and dismissive.
__________________
New to the board? Check out the guidelines
| Color Picker | Blogification |
¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
With all its sham, drudgery, and broken dreams, it's still a beautiful world.

Last edited by BuzzLY; 06-25-2004 at 01:04 AM.
BuzzLY is offline   Reply With Quote
Old 06-25-2004, 01:25 PM   #12
hodge
Member
 
Join Date: Jun 2004
Posts: 30
<quote>
I think this is more in line with what I was looking for, but thanks for the link nice effort to help someone out .
<end quite>

buzzLY;

this is really moving into an area I choose not to respond any more with. So this will be my last reply to your statements. But first I would offer that you really look up the words
Condescending and dismissive I don't really think that the wording from above in my quote
Nice effort to HELP "now thats a key word" someone out will be attached to the real meaning of them.
Your attempt to use my statement in a manor
other then the natural intent is in fact Condescending . The truth is using a phrase with the wording HELP will never fit into a sentence with Condescending overtones.
Being as nothing is really getting done going down this path as stated I choose to not respond to the idle mis-use of my attempt to acknowledge your effort to assist in the link you provided.
I came here to seek some direction with a positive manor and have spent a great deal of time "Off subject" doing word games that will serve NO One.
Have a great day I'm off to other matters that don't require endless amounts of word battles.
It's been a venture one that I'm sure will not impose a lasting image to seek any other direction from this site. Now one can only ask what other new viewers would think taking into account this little Self imposed correctional direction with my statements of no harm or intent pointed before they pose a question.
Some times when you think you win you are really lead to be leave such to gain closure.
hodge is offline   Reply With Quote
Old 06-26-2004, 05:03 AM   #13
Weedpacket
Custom User Title™
 
Weedpacket's Avatar
 
Join Date: Aug 2002
Location: Rapid Offensive Unit "Foreign Object Damage"
Posts: 19,137
Well, I dunno. After writing the code, describing its use, and providing an example (the bit after the line that says "//Example"), I thought I had managed to make things self-evident. To then see a (weakly-written) post asking if anyone had got it working (six months later) and if they had an example is disconcerting, to say the least. Some people have to start wondering about some other people.

As for whether you were being condescending or not: using the word "help" does not guarantee noncondescension despite what you (appear to) say.

Perhaps if you were a bit more careful when you are writing, paying a bit more attention to things like punctuation and grammar for example, people would be less likely to misunderstand you - those rules you learned when you were learning English are there for a reason. Just a thought.
__________________
On two occasions I have been asked [by Members of Parliament], "Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?" I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question.
Weedpacket is offline   Reply With Quote
Old 06-27-2004, 10:09 PM   #14
BuzzLY
2($infinity) && $beyond
 
BuzzLY's Avatar
 
Join Date: Nov 2002
Location: Star Command
Posts: 2,535
Well... judging from the last post, I think we're dealing with someone using a tranlating program. At least, I hope this misunderstanding is due to English being a second language, and not due to horrible grammar and spelling errors. If English is indeed a second language for you, then I retract my statement. However, please note, that to anyone that speaks fluent English, your statement could easily be taken as condescending.

In any case, hodge, regardless of whether you intended to be condescending or not, the point I was trying to make was that you seem to be requesting something that was already provided, and that if you were requesting something else, you needed to be a little more clear about what you wanted. I don't call that "word games." I call that "say what you mean."
__________________
New to the board? Check out the guidelines
| Color Picker | Blogification |
¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
With all its sham, drudgery, and broken dreams, it's still a beautiful world.
BuzzLY is offline   Reply With Quote
Old 06-28-2004, 07:08 AM   #15
Weedpacket
Custom User Title™
 
Weedpacket's Avatar
 
Join Date: Aug 2002
Location: Rapid Offensive Unit "Foreign Object Damage"
Posts: 19,137
Quote:
Originally posted by BuzzLY
Well... judging from the last post, I think we're dealing with someone using a tranlating program.
Ummm.... rereading it, yeah, I do think you may be right. "Manner" is misspelled, but even software translators might make that mistake. The poster's claims of being in Atlanta (and having an Atlanta-based ISP) are of course not substantial enough to go on.

The linebreaks do suggest a cut-and-paste.
__________________
On two occasions I have been asked [by Members of Parliament], "Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?" I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question.

Last edited by Weedpacket; 09-08-2004 at 05:29 AM.
Weedpacket is offline   Reply With Quote
Reply

Bookmarks


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Forum Jump


All times are GMT -4. The time now is 05:44 PM.






Acceptable Use Policy

internet.comMediabistrojusttechjobs.comGraphics.com

WebMediaBrands Corporate Info


Advertise | Newsletters | Feedback | Submit News

Legal Notices | Licensing | Permissions | Privacy Policy


Powered by vBulletin® Version 3.7.2
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.