• (cs)

    Cents doesn't means cents...

    Makes cents I suppose. rimshot

  • (cs) in reply to Cyrus

    But what if management later decides that price-in-cents, subsequently price-in-tenths-of-cents, subsequently price-in-hundreths-of-cents should now be price-in-roman-numerals?

  • lrucker (unregistered)

    Long ago - so long that it's probably safe to mention it, as there's no chance anyone will ever ask me to code in it - I wrote RPG programs (Report Program Generator, for you kiddies).

    Now, as you'd imagine, RPG is good at generating reports, specifically on line printers. It knows what line it's on, how far it is to the end of the page, all sorts of wonderful things. If you want the subtotal 5 lines from the bottom, that's one line of code.

    A previous programmer did not get this. He thought in Cobol and he wrote in Cobol, even when using RPG. He wrote his own line count routines. He wrote his own page count routines. Something that should have been 10 lines of code (in a language where something with 20 lines of code was a seriously complex operation) turned into 10 pages (heaven forbid he use the include functionality to reuse his page counters). And of course his code had bugs, and those bugs were buried in all the cruft.

    My boss could not understand why I'd rewrite any program of his that I had to work on. Wouldn't it just be faster to find the bug? But then, my boss was only in the software business because back when he'd owned an office products supply company, he'd noticed that before selling a 5 cent pencil you had to buy a 4 cent pencil, but before selling a $10K piece of software you only needed to buy a $5 floppy.

  • (cs)

    Any class that takes currency as a floating point value is a wtf in itself quite apart from the changing database value.

  • (cs)

    So not only do we have a complete logic WTF by pete, we also have a bit of a technical one. A decimal / int / float in .net is a 'primitive' and can live it's merry life on the statck.

    However Money myMoney = new Money(0.10); // $.10, is creating new object, of type 'Money' which lives its not so happy life on the managed heap, just sitting their waiting to be cleaned up. I'm guessing in a financial system, there is a hell of a lot of 'Money' that needs to be manipulated in code.

    Work that Garbage Collector!

  • Not So Bad (unregistered)

    Well, the idea isn't so bad. Save a number with the precision you need in a simple integer field. The problem is, there is implied information (level of precision) that wasn't captured in the database.

    Old school game programmers will recognize this as a "fixed point" technique; representing floats as integers, so you might have 16.16 (16 bits for the integer part, 16 bits for the floating point part). Really handy back when floating point units weren't quite as fast and DOOM ran without a 3D card!

    He should have had his class spit out another column that documented the precision. Or, just used the MONEY type provided by SQL. :-)

  • Kluge Doctor (unregistered)

    I guess management is fond of throwing good price_in_cents after bad.

    Blessed are those techies that are managed by former techies.

  • (cs)

    Millions for nonsense, but not one cent for entropy.

  • (cs) in reply to Not So Bad
    Not So Bad:
    Well, the idea isn't so bad. Save a number with the precision you need in a simple integer field. The problem is, there is implied information (level of precision) that wasn't captured in the database.

    Old school game programmers will recognize this as a "fixed point" technique; representing floats as integers, so you might have 16.16 (16 bits for the integer part, 16 bits for the floating point part). Really handy back when floating point units weren't quite as fast and DOOM ran without a 3D card!

    He should have had his class spit out another column that documented the precision. Or, just used the MONEY type provided by SQL. :-)

    Well... Sql Money and .net decimal are actually stored as 3 integers, and works for arguments sake in the way you mention... So yes, not such a bad idea over using floats; but this has just been implemented with a complete lack of knowledge that Sql Money and decimal exist in Sql and .net respectively, as well as being implemented incorrectly. If this is MSSQL it’s quite hard to miss the money type when using the inbuilt WYSWIG table designer… you would think Pete would have seen it and enquired a bit further as to what it did before trying to reinvent the wheel… badly.

    Pete also strikes me as someone who thought ‘databases are just where I shove data’, as without the application code there is no way to interpret the real meaning of the data in the cents column.

    Sigh

  • Bullwark (unregistered) in reply to Kluge Doctor
    Kluge Doctor:
    Blessed are those techies that are managed by former techies.

    This presumes that a manager who is a former techie: a) was good at being a techie. b) isn't set on having everything work the way it did in 1975.

  • kevinc (unregistered)

    i like an ending like this. it's the feel-good wtf of the week.

  • TopCod3r (unregistered)

    Doesn't it seem obvious to anyone else here that Andy is unfamiliar with futures trading and commission structures, and has an inferiority complex about his own code? It seems like he is publicly lambasting Pete in order to try to cover his own hide. So he should have looked at the code in the money class a long time ago before monkeying around with Pete's code trying to "fix" things. Then maybe he wouldn't be in such a mess.

  • Wyatt (unregistered) in reply to Grovesy
    Grovesy:
    So not only do we have a complete logic WTF by pete, we also have a bit of a technical one. A decimal / int / float in .net is a 'primitive' and can live it's merry life on the statck.

    However Money myMoney = new Money(0.10); // $.10, is creating new object, of type 'Money' which lives its not so happy life on the managed heap, just sitting their waiting to be cleaned up. I'm guessing in a financial system, there is a hell of a lot of 'Money' that needs to be manipulated in code.

    Work that Garbage Collector!

    If this is C#, we aren't shown the class definition, so it may be a struct rather than a class. If "Money" was a struct, it would still live on the stack.

  • (cs)
    Despite that, he was able to sneak in a little change – er, adaptation. price_in_cents became a DECIMAL and the system became a little saner.

    Were alex working in MySQL 4.1, this would have been a horrible mistake. All operations on MySQL's DECIMAL (arbitrary precision) type are done with float operators. So you'll have all the standard floating point errors.

    For databases without arbitrary precision math, storing currency in an integer is the right choice.

  • A Nonny Mouse (unregistered)

    gah.

    why do people think they know better? walked into a module a while's back where the developer had stripped all dates of //'s, done a bit of jiggery pokery and lobbed his own date-format into the db. ported the project to servers in europe and lost all the content. go locale, go.

  • wisetoyourgames (unregistered) in reply to TopCod3r

    Pete? Is that you?

    It has to be.

  • TopCod3r (unregistered) in reply to wisetoyourgames

    No, it is not me

  • snark (unregistered) in reply to Not So Bad
    Not So Bad:
    Well, the idea isn't so bad. Save a number with the precision you need in a simple integer field. The problem is, there is implied information (level of precision) that wasn't captured in the database.

    Old school game programmers will recognize this as a "fixed point" technique; representing floats as integers, so you might have 16.16 (16 bits for the integer part, 16 bits for the floating point part). Really handy back when floating point units weren't quite as fast and DOOM ran without a 3D card!

    He should have had his class spit out another column that documented the precision. Or, just used the MONEY type provided by SQL. :-)

    That's a neat perf trick of "representing floats as integers".

    Just one question how does one represent the float value 1 X 2e16 in the "fixed point" you describe? Or 1 X 2e-16? I got an idea. Use some of the bits for the matissa and some for the exponent. I think I'll call it a gliding point.

  • KG (unregistered) in reply to Wyatt
    Wyatt:
    If this is C#, we aren't shown the class definition, so it may be a struct rather than a class. If "Money" was a struct, it would still live on the stack.

    Actually, I'm pretty sure the C# compiler performs escape-analysis (I think that's what it's called). Basically, if an object's reference leaves a function, it is allocated on the heap. Otherwise, it is allocated on the stack.

    Of course, declaring Money as a struct guarantees it's always allocated on the stack.

  • sf (unregistered) in reply to merreborn
    merreborn:
    Despite that, he was able to sneak in a little change – er, adaptation. price_in_cents became a DECIMAL and the system became a little saner.

    Were alex working in MySQL 4.1, this would have been a horrible mistake. All operations on MySQL's DECIMAL (arbitrary precision) type are done with float operators. So you'll have all the standard floating point errors.

    For databases without arbitrary precision math, storing currency in an integer is the right choice.

    My first thought, too. :)

  • Toodle (unregistered) in reply to Cyrus
    Cyrus:
    Cents doesn't means cents...

    Makes cents I suppose. rimshot

    sniffs and wrinkles his nose

    That comment really has a bad cent!

  • John Doe (unregistered) in reply to snark
    snark:
    Just one question how does one represent the float value 1 X 2e16 in the "fixed point" you describe? Or 1 X 2e-16?
    1 x 2e16 is an overflow. You can't represent that, just like you can't represent 1 x 2e32 in a 32 bit integer value. The biggest value (unsigned) is 65535 + 65535/65536. 1 x 2e-16 is 0x00000001 in hex, the smallest possible value.
    snark:
    I got an idea. Use some of the bits for the matissa and some for the exponent. I think I'll call it a gliding point.
    Don't forget one bit for the sign, and you'll end up with IEEE 754. But I assume you're sarcastic here ;)
  • John Doe (unregistered) in reply to John Doe
    John Doe:
    snark:
    Just one question how does one represent the float value 1 X 2e16 in the "fixed point" you describe? Or 1 X 2e-16?
    1 x 2e16 is an overflow. You can't represent that, just like you can't represent 1 x 2e32 in a 32 bit integer value. The biggest value (unsigned) is 65535 + 65535/65536. 1 x 2e-16 is 0x00000001 in hex, the smallest possible value.
    Oops, 1 x 2e16 is 20,000,000,000,000,000 of course. I meant (1 x) 2^16, and (1 x) 2^-16.
  • PE (unregistered) in reply to Not So Bad

    That technique can still be used in multiplayer games to store values that need to stay exactly in sync across different platforms.

  • (cs) in reply to Toodle
    Toodle:
    Cyrus:
    Cents doesn't means cents...

    Makes cents I suppose. rimshot

    sniffs and wrinkles his nose

    That comment really has a bad cent!

    Fortunately it is not old. It has some currency!

  • (cs)

    From the way this started, I thought this was going to be from somebody at my company, but the identifier price_in_cents made me realize that's not the case. Here it would have been more to the tune of pr_cnt. way more human readable.

  • Demaestro (unregistered)

    I wouldn't have even gone to a decimal.. just store everything in cents. Best design is always store the lowest possible unit.

    You don't need dollars just cents. How many dollars can be calculated based on the amount of cents.

    I do the same for time.. why store hours and fraction of hours.. or minutes and fraction of minutes... when you can store seconds and convert to get either?

  • mookers (unregistered) in reply to ParkinT

    And it's cold. Quite schilling, in fact. A bit heavy too. At least fifty pounds.

  • mookers (unregistered) in reply to ParkinT
    ParkinT:
    Toodle:
    Cyrus:
    Cents doesn't means cents...

    Makes cents I suppose. rimshot

    sniffs and wrinkles his nose

    That comment really has a bad cent!

    Fortunately it is not old. It has some currency!

    And it's cold. Quite schilling, in fact. A bit heavy too. At least fifty pounds.

  • Pygon (unregistered) in reply to ParkinT
    ParkinT:
    Toodle:
    Cyrus:
    Cents doesn't means cents...

    Makes cents I suppose. rimshot

    sniffs and wrinkles his nose

    That comment really has a bad cent!

    Fortunately it is not old. It has some currency!

    Maybe things will change.

  • Jon (unregistered) in reply to Pygon
    Pygon:
    ParkinT:
    Toodle:
    Cyrus:
    Makes cents I suppose. *rimshot*
    *sniffs and wrinkles his nose*

    That comment really has a bad cent!

    Fortunately it is not old. It has some currency!
    Maybe things will change.
    What a rand-om remark!

  • Mr. Consultant (unregistered)

    At least it was easy to fix. All you need to do is hire a consultant to add some XML.

  • (cs) in reply to Mr. Consultant
    Mr. Consultant:
    At least it was easy to fix. All you need to do is hire a consultant to add some XML.

    What's the expression?

    "XML is like violence. If it doesn't solve your problem, use more."

  • McDuck (unregistered) in reply to Demaestro
    Demaestro:
    I wouldn't have even gone to a decimal.. just store everything in cents. Best design is always store the lowest possible unit.
    They needed precision to fractions of a cent.
    Jon:
    Pygon:
    ParkinT:
    Toodle:
    Cyrus:
    Makes cents I suppose. *rimshot*
    *sniffs and wrinkles his nose*

    That comment really has a bad cent!

    Fortunately it is not old. It has some currency!
    Maybe things will change.
    What a rand-om remark!
    You guys are all loonies.

  • chaos95 (unregistered) in reply to ParkinT

    All of you go to your rooms! Bad! Bad puns! Shoo!

  • Izzy (unregistered) in reply to snoofle
    snoofle:
    But what if management later decides that price-in-cents, subsequently price-in-tenths-of-cents, subsequently price-in-hundreths-of-cents should now be price-in-roman-numerals?
    If the Americas ever unify their currencies and settle on the Eight Reale "dollar," they'll be figuring commission on pieces of eight. [parrot] Pieces of Eight! Pieces of Eight! Squawk! [/parrot]

    At least it would be binary.

    Captcha: Gold-Pressed Latinum

  • Harrow (unregistered) in reply to snark
    snark:
    I got an idea. Use some of the bits for the matissa and some for the exponent. I think I'll call it a gliding point.
    Not enterprisey enough. I'm gonna use some of the bits for the exponent, some for the mantissa part, and some for the radix. That way, I can have exact fraction precision in any number base. Need to store $0.0303? No problem: radix=10, exp=-4, fract=303.

    Yes, you may well laugh now. But when beings from a superior civilization on another planet come 175,000 light-years to bank their money with us, and happen to use base 12, and are VERY particular about roundoff errors, and have great big honkin' scrotum-shrivelin' death ray cannons, then we'll see, hah.

    -Harrow.

  • (cs) in reply to Wyatt
    Wyatt:
    Grovesy:
    So not only do we have a complete logic WTF by pete, we also have a bit of a technical one. A decimal / int / float in .net is a 'primitive' and can live it's merry life on the statck.

    However Money myMoney = new Money(0.10); // $.10, is creating new object, of type 'Money' which lives its not so happy life on the managed heap, just sitting their waiting to be cleaned up. I'm guessing in a financial system, there is a hell of a lot of 'Money' that needs to be manipulated in code.

    Work that Garbage Collector!

    If this is C#, we aren't shown the class definition, so it may be a struct rather than a class. If "Money" was a struct, it would still live on the stack.

    Good point, for some reason I just assumed it was part of a class definition ...

  • (cs) in reply to snark
    snark:
    Not So Bad:
    Well, the idea isn't so bad. Save a number with the precision you need in a simple integer field. The problem is, there is implied information (level of precision) that wasn't captured in the database.

    Old school game programmers will recognize this as a "fixed point" technique; representing floats as integers, so you might have 16.16 (16 bits for the integer part, 16 bits for the floating point part). Really handy back when floating point units weren't quite as fast and DOOM ran without a 3D card!

    He should have had his class spit out another column that documented the precision. Or, just used the MONEY type provided by SQL. :-)

    That's a neat perf trick of "representing floats as integers".

    Just one question how does one represent the float value 1 X 2e16 in the "fixed point" you describe? Or 1 X 2e-16?

    One does not, just as one does not represent 2^32 in a 32-bit integer.

  • (cs) in reply to Harrow
    Harrow:
    snark:
    I got an idea. Use some of the bits for the matissa and some for the exponent. I think I'll call it a gliding point.
    Not enterprisey enough. I'm gonna use some of the bits for the exponent, some for the mantissa part, and some for the radix. That way, I can have exact fraction precision in any number base. Need to store $0.0303? No problem: radix=10, exp=-4, fract=303.

    Yes, you may well laugh now. But when beings from a superior civilization on another planet come 175,000 light-years to bank their money with us, and happen to use base 12, and are VERY particular about roundoff errors, and have great big honkin' scrotum-shrivelin' death ray cannons, then we'll see, hah.

    -Harrow.

    Of course the exponent, mantissa, and radix should be stored in an Xml file, and we need some Factories, Messages, and Commands... Perhaps a Controller as well, and some class with the word 'strategy ' in, I like strategy

  • (cs) in reply to Carnildo
    Carnildo:
    snark:
    Not So Bad:
    Well, the idea isn't so bad. Save a number with the precision you need in a simple integer field. The problem is, there is implied information (level of precision) that wasn't captured in the database.

    Old school game programmers will recognize this as a "fixed point" technique; representing floats as integers, so you might have 16.16 (16 bits for the integer part, 16 bits for the floating point part). Really handy back when floating point units weren't quite as fast and DOOM ran without a 3D card!

    He should have had his class spit out another column that documented the precision. Or, just used the MONEY type provided by SQL. :-)

    That's a neat perf trick of "representing floats as integers".

    Just one question how does one represent the float value 1 X 2e16 in the "fixed point" you describe? Or 1 X 2e-16?

    How often does a company sell something that costs 10 quadrillion dollar?

  • kaalikas (unregistered) in reply to KG

    actually the CRL allocates all reference types (with a few exceptions like stackalloc'ed non-reference type arrays) on the heap and non-reference types (including structs) on the stack (as long as they are not boxed) or inside reference types on the heap

  • (cs) in reply to ParkinT

    Being from the UK; I think that pound for pound, it seems like a Sterling solution to the problem. ;)

  • nick (unregistered)

    Price in Nonsense

    What a great title!

  • Trevor (unregistered)

    So that's how this happened!

    http://www.24.com/news/?p=worlda&i=789135

  • Sean (unregistered)

    His solution will lead to a future WTF. Don't use floating point for money.

  • Ida Know (unregistered) in reply to ParkinT
    ParkinT:
    Toodle:
    Cyrus:
    Cents doesn't means cents...

    Makes cents I suppose. rimshot

    sniffs and wrinkles his nose

    That comment really has a bad cent!

    Fortunately it is not old. It has some currency!
    Could we please change the subject?

  • KG (unregistered) in reply to kaalikas
    kaalikas:
    actually the CRL allocates all reference types (with a few exceptions like stackalloc'ed non-reference type arrays) on the heap and non-reference types (including structs) on the stack (as long as they are not boxed) or inside reference types on the heap

    http://www.ibm.com/developerworks/java/library/j-jtp09275.html

    Ahh, here's where I read about escape analysis. I guess I confused the Java runtime with the .NET CLR on this issue. Although, I'm surprised that MS didn't duplicate this technique, seeing as how much from Java they did rip off.

  • knock it off... (unregistered) in reply to Sean
    Sean:
    His solution will lead to a future WTF. Don't use floating point for money.

    Thanks... I was also going to post this. It is completely ludicrous to use floating point types for currency, be it in the database or in the code.

    In Europe it is quite simple: Since the adoption of the Euro it is compulsory to perform currency calculations with 4 decimal places.

    So, best bet is using an integer type and treat all values as ten thousandths of a Euro. Placing the decimal point is only necessary for user interaction and is moreover trivial.

    If different currencies are required, the currency information has to be kept anyway, thus precision information can be stored as well.

    Of course in that case an extra table is necessary for the currency info by all means. Otherwise we'd have to expect solutions where two additional fields (currency and precision) have to be added to each table requiring monetary values... normalization, anyone? ;o)

    Pete's solution was not so bad per se, he just was not able to anticipate future requirements and create a model capable of such changes.

    BTW, it would have been quite trivial to update the data after each precision change.

    An interesting question is - was Pete really that incompetent, or just sloppy? Perhaps he used an integer because he did not know of the DECIMAL-type ;o) But then, he wrote a convenience class to convert decimal monetary values (which are dumb in the code anyway, but perhaps others insisted on using them) into his database representation... so at least it seems he was aware of the problem to some extent. But as long as the API supports using decimal monetary values in the code, not much is gained - the precision errors inherent to the IEEE 754 standard would be accumulated in the calculations. Storing these increasingly inaccurate values as floats or integers does not make a lot of difference.

    Therefore Andy's solution of changing the type to DECIMAL makes matters even worse really, because most probably they did nothing to change the use of floating point arithmetic in the code - they are just asking for inexplicable errors in their monetary calcuations.

    It seems that the managment was more competent, because they wouldn't let the changes in the database happen - but more likely this was just by chance, they just didn't like change in general ;o)

  • ludus (unregistered) in reply to Not So Bad
    Not So Bad:
    Well, the idea isn't so bad. Save a number with the precision you need in a simple integer field. The problem is, there is implied information (level of precision) that wasn't captured in the database.

    Old school game programmers will recognize this as a "fixed point" technique; representing floats as integers, so you might have 16.16 (16 bits for the integer part, 16 bits for the floating point part). Really handy back when floating point units weren't quite as fast and DOOM ran without a 3D card!

    He should have had his class spit out another column that documented the precision. Or, just used the MONEY type provided by SQL. :-)

    Quake 1 makes use of the same technique. ;) IT also houses a few other interresting tricks.

Leave a comment on “Price in Nonsense”

Log In or post as a guest

Replying to comment #:

« Return to Article