|
Luc Pattyn wrote: hould have emitted IL code
Good idea - but it would have defeated the purpose of the timing tests. I would have written the IL code as assembler: numeric index into jump table, or string pointer table maybe. I was more interested in how the compiler would handle the problem than I was in how I would handle it!
PiebaldConsult came up with an idea for a web service backed by a database, so I mocked up the database version (with a SqlCE DB) that works up to 1,000,000 - a total of a 92MB DB - it seems pretty fast and the code is pretty small. Do you think I should post it as a new Tip / Trick: "Numbers to words : the Extra Credit version"?
Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.
|
|
|
|
|
OriginalGriff wrote: it would have defeated the purpose
rather than write code, you should have read this then: Something You May Not Know About the Switch Statement in C/C++[^]. And if you are convinced C# may behave differently, it would deserve a real article.
OriginalGriff wrote: Do you think I should post it as a new Tip / Trick
Absolutely, a tip or article. And please include an SQL file with the data, so others can set up their own DB.
OriginalGriff wrote: Five hundred and twenty three
There seems to be one more issue that needs getting settled: should or shouldn't you use a hyphen in those inverted decimal-and-unit combinations? And if both are acceptable, how to let the user choose?
|
|
|
|
|
Luc Pattyn wrote: should or shouldn't you use a hyphen in those inverted decimal-and-unit combinations?
Thank you for pointing out this problem; you are indeed quite correct and there should be a hyphen between the tens digit and the units digit for all values between 21 and 99, excepting (of course) those integrally divisible by ten. This also applies to such numbers when considered as part of a larger number: "one thousand and sixty-seven" or "three hundred and fourty-eight thousand". In addition, there may be a comma between the magnitude indicator and the lesser value ("one thousand, three hundred and sixty-seven") although this is not compulsory (unless there is a decimal point in the number, in which case it should appear at each three digit position to the right of the decimal).
I had completely forgotten this point, and have modified the Tip / Trick accordingly. In my defence, it has been many years since I last wrote a cheque and thus any numbers as words! Even then, to exceed one thousand on a personal cheque was not an everyday occurrence...
I have corrected this, and provided credit as is only appropriate.
Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.
|
|
|
|
|
Thanks for the clarification, and of course the credit.
I didn't know at all about the thousands separators turning into comma's (and I hope you really mean "," and not "comma").
How about the ultimate edition, dealing with floating-point numbers? (could be double, float, decimal)
|
|
|
|
|
Luc Pattyn wrote: How about the ultimate edition, dealing with floating-point numbers?
I think that is the "Pro Ultimate Gold Team Edition for Workgroups Turbo CRXVI-DiD" due for simultaneous release with the "Hades Low Temperature Food Storage Conditions" application. The release date of the later is, unfortunately, beyond my control - but is estimated to be when Microsoft release a bug-free version of Visual Studio.
Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.
|
|
|
|
|
The beauty of the database solution is that you can easily add globalization -- a new language/culture is simply another column in the table.
|
|
|
|
|
Yep. And you can outsource it, all it takes is a linguist, not a programmer. Maybe there is a business opportunity here.
Or there could soon be a new homework assignment: given a numbers-to-words database in language A, translate it automatically to language B.
|
|
|
|
|
|
Hi,
I know you are not totally serious but what is the correct way and why should it not be faster than a large switch? I think the created IL code behaves similar to a very large if-then-elseif construct. Thus the switch-solution will get slower if you increase the range of supported numbers.
btw: I would create a "real algorithm" to produce the strings and pair it with a dictionary as a cache.
Robert
|
|
|
|
|
There are many ways to do a switch: For example, you could set up a table of delegates (each delegate referring to a method which executes the case block). To implement the switch for a numeric value, you need only use the parameter as an index into the table. No comparisons are required, so executions speed is excellent and the time taken to get to the code for the case block is the same for each case. To implement this with an if-then-else requires a comparison for each case in turn - this is understandably slower, and the execution time differs for each case.
There are other ways - the above is only suitable for densely populated cases - but I hope that makes some sense!
Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.
|
|
|
|
|
Robert Rohde wrote: I think the created IL code behaves similar to a very large if-then-elseif construct. Thus the switch-solution will get slower if you increase the range of supported numbers.
Wrong. IL has a special instruction for switch which the JIT translates into a jump table. Switches of consecutive integer values (so that a table without large holes is possible) don't get slower if you add cases. Switches of strings are implemented using a Dictionary<string, int> and the IL switch instruction on the resulting int.
|
|
|
|
|
|
|
Can you think of why a programmer would ever use a string to act as a bitmap field?
e.g.
DECLARE @Bitmap varchar(20)
SELECT @Bitmap = '00110100100011011110'
The beauty of bitmasks is that the values are compact (at one bit each) and you get the benefit of bitwise ANDing and ORing.
I winced at this, but can you think of an instance where this might make sense (except for the obvious "Hey, I just read a cool article about bitmaps! Computer scientists use 'em all the time.")
|
|
|
|
|
Yes; because he didn't ask me for advice first.
To make it worse, he used 8s rather than 0s. By the time he showed me what he'd done it was too late and not worth the trouble to fix, so it's still like that in production.
Neither of us works for that company anymore, so we just laugh about it. What the heck, it works!
|
|
|
|
|
I started out on a computer with a hex keyboard and learned there how to mask or test some bits. Nowadays I still often use them, for example in some entity in a web application.
But along the way I met several young and promising code monkeys who easily understood that you should use some kind of integer for that and what the bits are good for. But all of them had real trouble with this arcane AND and OR stuff. I guess the real horror here is, how somebody can have trouble understanding such a fundamental thing.
A while ago he asked me what he should have printed on my business cards. I said 'Wizard'.
I read books which nobody else understand. Then I do something which nobody understands. After that the computer does something which nobody understands. When asked, I say things about the results which nobody understand. But everybody expects miracles from me on a regular basis. Looks to me like the classical definition of a wizard.
|
|
|
|
|
"But all of them had real trouble with this arcane AND and OR stuff."
Believe me, I was in a fog about that my first two years programming. And XOR made me weep like a little girl!
Thanks for sharing your dark secrets, Mr. Wizard.
|
|
|
|
|
I must admit in the dim and distant past I did something not terribly dissimilar to that. Indeed if you search MSDN you can still find the evidence.
http://msdn.microsoft.com/en-us/library/aa239702(VS.60).aspx[^]
Now, It's too long ago for me to try justify exactly what I was doing, but here is what I remember of it:
1. The "bits" in this case represented meta-data which were stored in an XML document.
2. I wasn't going to be AND'ing or OR'ing the fields as a whole.
3. Any performance or space savings from using actual bits would have been outweighed by the benefit of being able to see the string of 1s and 0s in XML, rather than a cryptic Numerical value
4. Keeping the string of 1s and 0s in XML but actual bit logic in code would have meant translating back and forth needlessly.
So there it is.
I'm a huge fan of bitmap fields and use them all the time, but in that instance and at that time I felt comfortable with a string.
But yes, my default attitude is that a string is rarely the right way to go. 99% of the time I'd expect it to be a bad idea, and the remaining 1% of times I'd expect it to be seriously debatable.
|
|
|
|
|
Cool article. Thanks for the thoughts.
|
|
|
|
|
Thanks for the excuse to go back and look at that again.
It's hard to believe that back then I thought that CCustomerCol was a good naming convention.
And as for LetXML and GetXML!?!?!
To this day nobody has ever noticed (or at least admitted noticing) the following:
CustCol.Customer(1).Company = "LA"
CustCol.Customer(1).ContactName = "Sandy"
CustCol.Customer(1).Phone = "555-2312"
In the movie LA Story Sarah Jessica Parker's character is called Sandy and gives Steve Martin's character her phone number which is...555-2312.
The movie happened to be on tv in the background when I was writing the article. Just when I needed a bit of sample data that scene happened.
According to
http://www.radivarl.demon.co.uk/nick/media/555.htm[^]
I misspelled her name.
|
|
|
|
|
Oh yeah, SaNdee. Just after Steve Martin noted that at least she had a normal name.
Best line in that movie when SaNdee persuades Steve to get an enema. Afterwards, she says something like "that really clears my head" and Steve replies, "clears your head? You must be doing it wrong."
I'm guessing the Let and Get statements were more in vogue at the time you wrote the article what with VB6 and all.
|
|
|
|
|
With a shudder I remember my introduction to programming on a ZX81 with 1K RAM.
After quickly exhausting the possibilities of BASIC in a 1K program (even when programs are stored tokenized, with each keyword a single byte), I had to resort to machine code. A program then consisted of a subroutine (using GOSUB/RETURN) that POKE'd bytes into memory, reading them from hexadecimal strings stored in DATA statements such as.
10 DATA "3AFB3C2A1F"
I had to manually write these hex strings by looking up Z80 opcodes and converting registers etc into bitfields (not enough memory to run an assembler).
Once it was all in memory, I'd write it to a file (cassette-based), then write another program to load the binary data and transfer control into it (can't remember how that was achieved though).
On the other hand, it taught me all the basics of programming, in a very real and demanding environment.
Binary though, I can see no good reason for that.
|
|
|
|
|
Man, this is the best thread ever. Talk about walks down memory lane.
Your ZX81 tape recorder worked. You lucky sod.
My first computer was a second hand zx81, that never managed to talk to the tape recorder, no matter how I tried.
Every time I needed the ZX81 to do anything I had to write the code again from scratch.
Tim Hartnell's books became well thumbed and dog eared.
Am I right in recalling the RANDOMIZE keyboard being involved in launching machine code? I always thought that was funny because genuinely you never had any idea if the string of crap you transcribed would work. RANDOMIZE always seemed appropriate.
Still. At the age of 10 the zx81 showed me what I wanted to do for a living and 26 years later I get paid for doing it.
If Clive Sinclair had sold "Build Your Own Hedge Fund" kits I'd probably be broke and/or in jail by now.
You know what? that's my new sig.
|
|
|
|
|
Ditto, but replace ZX81 with Sinclair Spectrum (you must be a couple of years older than me )
<Shivers> Hedge Fund Management</Shivers> So lucky that didn't happen.
ragnaroknrol The Internet is For Porn[^]
Pete o'Hanlon: If it wasn't insulting tools, I'd say you were dumber than a bag of spanners.
|
|
|
|
|
I might not be older than you.
The Spectrum was available when I got my ZX81. My mother found one for £10 in
a second hand shop. Hence the non working tape recorder issue.
I upgraded to a Spectrum +2 in 1988.
I convinced my mother to spend over £200 (Irish) on the +2 by keying in the following program in the store:
10 Print "Tick"
20 Pause 50
30 Print "Tock"
40 Pause 50
50 GOTO 10
I was rushing to get something up on screen, and didn't have time for CLS's
I fear we've strayed a little from the topic.
-Richard
|
|
|
|