440,352 Members | 1,593 Online
Need help? Post your question and get tips & solutions from a community of 440,352 IT Pros & Developers. It's quick & easy.

# prePEP: Money data type

 P: n/a Here I send it. Suggestions and all kinds of recomendations are more than welcomed. If it all goes ok, it'll be a PEP when I finish writing the code. Thank you. .. Facundo ------------------------------------------------------------------------ PEP: XXXX Title: Money data type Version: $Revision: 0.1$ Last-Modified: $Date: 2003/10/17 17:34:00$ Author: Facundo Batista Status: Draft Type: Standards Track Content-Type: text/x-rst Created: 17-Oct-2003 Python-Version: 2.3.3 Abstract ======== The idea is to make a Money data type, basically for financial uses, where decimals are needed but floating point is too inexact. The Money data type should support the Python standard functions and operations. Rationale ========= The detail of the requeriments are in the Requirements_ section. Here I'll include all the decisions made and why, and all the subjects still in discussion. The requirements will be numbered, to simplify discussion on each point. As an XP exercise, I'll write the test cases before de class itself, so it'll comply exactly the requeriments of those tests. Please see them for an exact specification (and if you propose a different behaviour, please propose the corresponding test case if possible, thanks). Why Not To Use Tim Peters' FixedPoint? -------------------------------------- As we'll see in Requeriments, thera are items that FixedPoint doesn´t comply (because doesn't do something or does it different). It could be extended or modified to comply the Requeriments, but some needs are own to currency, and some features of FixedPoint are too much for Money, so taking them out will make this class simplier. Anyway, sometime maybe one could be made subclass of the other, or just make one from both. The code of the Money class is based in large part on the code of Tim Peters' FixedPoint: thank you for your (very) valuable ideas. Items In Discussion ------------------- 6. About repr(). Should myMoney == eval(repr(myMoney))? Requirements ============ 1. The sintaxis should be Money(value, [precision]). 2. The value could of the type: - another money (if you don't include *precision*, it get inheritated) - int or long (default *precision*: 0):: Money(45): 45 Money(45, 2): 45.00 Money(5000000000,3): 5000000000.000 - float (*precision* must be included):: Money(50.33, 3): 50.330 - string (*precision* get extracted from the string):: Money('25.32'): 25.32 Money('25.32', 4): 25.3200 - something that could be coerced by long() or float() 3. Not to support strings with engineer notation (you don't need this when using money). 4. Precision must be a non negative integer, and after created the object you could not change it. 5. Attributes decimalSeparator, currencySymbol and thousandSeparator could be overloaded, just to easy change them subclassing. This same *decimalSeparator* is that used by the constructor when receives a string. Defaults are:: decimalSeparator = '.' currencySimbol = '$' thousandSeparator = '' 6. Calling repr() should not return str(self), because if the subclass indicates that decimalSeparator='', this could carry to a confusion. So, repr() should show a tuple of three values: IntPart, FracPart, Precision. 7. To comply the test case of Mark McEahern:: cost = Money('5.99') percentDiscount = 10 months = 3 subTotal = cost * months discount = subTotal * (percentDiscount * 1.0) / 100 total = subTotal - discount assertEqual(total, Money('16.17')) 8. To support the basic aritmetic (+, -, *, /, //, **, %, divmod) and the comparisons (==, !=, <, >, <=, >=, cmp) in the following cases: - Money op Money - Money op otherType - otherType op Money - Money op= otherType OtherType could be int, float or long. Automaticlly will be converted to Money, inheritating the precision from the other component of the operation (and, in the case of the float, maybe losing precision **before** the operation). When both are Moneys, the result has the larger precision from both. 9. To support unary operators (-, +, abs). 10. To support the built-in methods: - min, max - float, int, long (int and long are rounded by Money) - str, repr - hash - copy, deepcopy - bool (0 is false, otherwise true) 11. To have methods that return its components. The value of Money will be (int part) + (frac part) / (10 ** precision). - getPrecision(): the precision - getFracPart(): the fractional part (as long) - getIntPart(): the int part (as long) 12. The rounding to be financial. This means that to round a number in a position, if the digit at the right of that position is bigger than 5, the digit at the left of that position is incremented by one, if it's smaller than 5 isn't:: 1.123 --> 1.12 1.128 --> 1.13 But when the digit at the right of that position is ==5. There, if the digit at the left of that position is odd, it gets incremented, otherwise isn't:: 1.125 --> 1.12 1.135 --> 1.14 Reference Implementation ======================== To be included later: - code - test code - documentation Copyright ========= This document has been placed in the public domain. Jul 18 '05 #1 Share this Question 24 Replies  P: n/a I've made a few edits for spelling and grammar, but I haven't cleaned up everything, and I haven't made any substantive changes to the text. Do with it what you will. Substantive issues: 1. I've seen lots of strange rounding policies in various nooks and crannies. Is there any way of specifying a rounding policy that would be used and inherited by the result money object? 2. Money objects are presumably immutable, the same as all other numeric objects. I've edited item 4 to presume this. 3. I haven't looked at Tim Peter's fixed point module, so I don't know how he handled this. Formatting characters should come from the current locale, or else should be supplied by an extended format method. In fact, I'd make this a requirement: there should be a formatting method that would handle the most common commercial formatting requirements, including zero and asterisk fill, floating and fixed currency symbol, and blanking the entire output field when it is zero. Also trailing minus sign, and so forth. 4. Repr should round trip. That's basic Python. This means that repr() should return something that the money() constructor understands regardless of the current locale setting. Making it human readable is the responsibility of either str(), the % operator or a hypothetical ..printf() method. 6. On operators. What happens to precision on multiplication and division? John Roth "Batista, Facundo" wrote in message news:ma*************************************@pytho n.org... Here I send it. Suggestions and all kinds of recomendations are more than welcomed. If it all goes ok, it'll be a PEP when I finish writing the code. Thank you. .. Facundo ------------------------------------------------------------------------ PEP: XXXX Title: Money data type Version:$Revision: 0.1 $Last-Modified:$Date: 2003/10/17 17:34:00 $Author: Facundo Batista Status: Draft Type: Standards Track Content-Type: text/x-rst Created: 17-Oct-2003 Python-Version: 2.3.3 Abstract ======== The idea is to make a Money data type, basically for financial uses, where decimals are needed but floating point is too inexact. The Money data type should support the Python standard functions and operations. Rationale ========= The detail of the requeriments are in the Requirements_ section. Here I'll include all the decisions made and why, and all the subjects still being discussed. The requirements will be numbered, to simplify discussion on each point. As an XP exercise, I'll write the test cases before the class itself, so it'll comply exactly the requeriments of those tests. Please see them for an exact specification (and if you propose a different behaviour, please propose the corresponding test case if possible, thanks). Why Not Use Tim Peters' FixedPoint? -------------------------------------- As we'll see in Requeriments, there are items that FixedPoint does not satisfy, either because it doesn't do something or does it differently. It could be extended or modified to comply with the Requeriments, but some needs are specific to currency, and some features of FixedPoint are unnecessarilly complex for Money, so taking them out will make this class simplier. Anyway, sometime maybe one could be made subclass of the other, or just make one from both. The code of the Money class is based in large part on the code of Tim Peters' FixedPoint: thank you for your (very) valuable ideas. Open Issues ------------------- 6. About repr(). Should myMoney == eval(repr(myMoney))? Requirements ============ 1. The syntax should be Money(value, [precision]). 2. The value is one of the following: - another money (if you don't include *precision*, it will be inheritated) - int or long (default *precision*: 0):: Money(45): 45 Money(45, 2): 45.00 Money(5000000000,3): 5000000000.000 - float (*precision* is required):: Money(50.33, 3): 50.330 - string (*precision* is extracted from the string):: Money('25.32'): 25.32 Money('25.32', 4): 25.3200 - any other object that could be input to the long() or float() constructors. 3. Strings with floats in engineering notation will not be supported. This is an unecessary complication. 4. Precision must be a non negative integer. 5. Attributes decimalSeparator, currencySymbol and thousandSeparator could be overloaded, just to easy change them subclassing. This same *decimalSeparator* is that used by the constructor when receives a string. Defaults are:: decimalSeparator = '.' currencySimbol = '$' thousandSeparator = '' 6. Calling repr() should not return str(self), because if the subclass indicates that decimalSeparator='', this could carry to a confusion. So, repr() should show a tuple of three values: IntPart, FracPart, Precision. 7. To comply the test case of Mark McEahern:: cost = Money('5.99') percentDiscount = 10 months = 3 subTotal = cost * months discount = subTotal * (percentDiscount * 1.0) / 100 total = subTotal - discount assertEqual(total, Money('16.17')) 8. To support the basic aritmetic (+, -, *, /, //, **, %, divmod) and comparison (==, !=, <, >, <=, >=, cmp) operators in the following cases: - Money op Money - Money op otherType - otherType op Money - Money op= otherType OtherType could be int, float or long. Automaticlly will be converted to Money, inheritating the precision from the other component of the operation (and, in the case of the float, maybe losing precision **before** the operation). When both are Moneys, the result has the larger of the two precisions. 9. To support unary operators (-, +, abs). 10. To support the built-in methods: - min, max - float, int, long (int and long are rounded by Money) - str, repr - hash - copy, deepcopy - bool (0 is false, otherwise true) 11. To have methods that return its components. The value of Money will be (int part) + (frac part) / (10 ** precision). - getPrecision(): the precision - getFracPart(): the fractional part (as long) - getIntPart(): the int part (as long) 12. The rounding to be financial. This means that to round a number in a position, if the digit at the right of that position is bigger than 5, the digit at the left of that position is incremented by one, if it's smaller than 5 isn't:: 1.123 --> 1.12 1.128 --> 1.13 But when the digit at the right of that position is ==5. There, if the digit at the left of that position is odd, it gets incremented, otherwise isn't:: 1.125 --> 1.12 1.135 --> 1.14 Reference Implementation ======================== To be included later: - code - test code - documentation Copyright ========= This document has been placed in the public domain. Jul 18 '05 #2

 P: n/a John Roth wrote: I've made a few edits for spelling and grammar, but I haven't cleaned up everything, and I haven't made any substantive changes to the text. Do with it what you will. Substantive issues: 1. I've seen lots of strange rounding policies in various nooks and crannies. Is there any way of specifying a rounding policy that would be used and inherited by the result money object? Amen, Hallelujah. I've followed up to Batista's similar post to python-dev by pointing out chapter and verse of EU regulations that _mandate_ "rounding to nearest and always round exactly-halfway UPWARDS", for example. As a side note, it's quite possible to spend inordinate amounts of attention on formatting. I would suggest that a fundamental 'money' class should first of all nail down the *computation* issues (just that variety of rounding specs is gonna be SUCH a bear...!) and receiving and returning information. Once that is done, one or more formatting functions can always be developed, be it as methods of the money class, a subclass, or whatever. No matter how it may look from Cobol, RPG, etc, correct and accurate computation that respects all relevant fiddly accounting regulations and practices IS the essence -- formatting requirements vary widely, and, if the base class does arithmetic "right" AND allows complete receiving and returning of information, extra formatting niceties can always be "plugged on top" later. But if the arithmetic is creaky -- e.g., _VB_'s "money" type -- all the cutesy formatting in the world won't ever fix it. Alex Jul 18 '05 #3

 P: n/a You're right, Alex, in that arithmetic is the real issue to be addressed, not formatting.. I also wonder if computation error should be tracked with this class, i.e. when you assign a Money type value of 1.21 then you know that the error is 0.05 at most. After that the usual error propagation rules apply for the arithmetic operations.. Best, Miklós -- PRISZNYÁK Miklós --- Jegenye 2001 Bt. ( mailto:je*********@parkhosting.com ) Egyedi szoftverkészítés, tanácsadás Custom software development, consulting http://jegenye2001.parkhosting.com Alex Martelli wrote in message news:Hg*******************@news1.tin.it... John Roth wrote: Substantive issues: 1. I've seen lots of strange rounding policies in various nooks and crannies. Is there any way of specifying a rounding policy that would be used and inherited by the result money object? As a side note, it's quite possible to spend inordinate amounts of attention on formatting. I would suggest that a fundamental 'money' class should first of all nail down the *computation* issues (just that variety of rounding specs is gonna be SUCH a bear...!) and receiving and returning information. Once that is done, one or more formatting functions can always be developed, be it as methods of the money class, a subclass, or whatever. No Alex Jul 18 '05 #4

 P: n/a Jegenye 2001 Bt wrote: You're right, Alex, in that arithmetic is the real issue to be addressed, not formatting.. I also wonder if computation error should be tracked with this class, i.e. when you assign a Money type value of 1.21 then you know that the error is 0.05 at most. After that the usual error propagation rules apply for the arithmetic operations.. That's not the way accountants do it in most situations. I think a numeric class with explicit error bounds and propagations may have its place, but that place is not as "the" type recommended for money computations in most Python application programs, IMHO. Alex Jul 18 '05 #5

 P: n/a Alex Martelli writes: 1. I've seen lots of strange rounding policies in various nooks and crannies. Is there any way of specifying a rounding policy that would be used and inherited by the result money object? Amen, Hallelujah. I've followed up to Batista's similar post to python-dev by pointing out chapter and verse of EU regulations that _mandate_ "rounding to nearest and always round exactly-halfway UPWARDS", for example. Are you serious about this? I thought financial computations with decimal arithmetic had been done in Cobol since the 1950's. They haven't gotten this stuff figured out by now? Can you crunch some calculation through a Cobol program and get an answer thtat's correct in the US and wrong in the EU? Jul 18 '05 #6

 P: n/a Ok, I'm not the accountant type. :D I'm an ex-physicist. ;) That's why I find controlled error bounds important. Best, Miklós Alex Martelli wrote in message news:5J*******************@news1.tin.it... That's not the way accountants do it in most situations. I think a numeric class with explicit error bounds and propagations may have its place, but that place is not as "the" type recommended for money computations in most Python application programs, IMHO. Alex Jul 18 '05 #7

 P: n/a "Paul Rubin" wrote in message news:7x************@ruckus.brouhaha.com... Alex Martelli writes: 1. I've seen lots of strange rounding policies in various nooks and crannies. Is there any way of specifying a rounding policy that would be used and inherited by the result money object? Amen, Hallelujah. I've followed up to Batista's similar post to python-dev by pointing out chapter and verse of EU regulations that _mandate_ "rounding to nearest and always round exactly-halfway UPWARDS", for example. Are you serious about this? I thought financial computations with decimal arithmetic had been done in Cobol since the 1950's. They haven't gotten this stuff figured out by now? Can you crunch some calculation through a Cobol program and get an answer that's correct in the US and wrong in the EU? COBOL's default rounding policy is to truncate. It has a second rounding policy that is invoked by the keyword ROUND (surprise, eh?) However, one of the things that COBOL arithmetic has is precise control of the number of decimal places at all points in a computation[1], so if you don't like either truncation or the effects of ROUND, then you simply maintain an additional decimal place or two and do it your way.[2] The difficulty here is that the control is maintained by declaring what the *output* of an operation looks like, and that's pretty much impossible for a language that doesn't have declarations. John Roth (who hopes to never see another COBOL program in his life - unless you're paying him big bucks, of course... [grin]) [1] Unless, of course, you're using the COMPUTE verb. [2] Unless that would run you over 18 digits. Why 18, I have no idea, and I'm afraid that most of the people on the original COBOL committee are no longer with us. Jul 18 '05 #8

 P: n/a "John Roth" writes: COBOL's default rounding policy is to truncate. It has a second rounding policy that is invoked by the keyword ROUND (surprise, eh?) However, one of the things that COBOL arithmetic has is precise control of the number of decimal places at all points in a computation[1], so if you don't like either truncation or the effects of ROUND, then you simply maintain an additional decimal place or two and do it your way.[2] Yeah, but what about the exact method of rounding, like the pre-PEP specifies 1.125 rounds down but 1.135 rounds up (or maybe it was the other way), while some other standard specifies always rounding down (or up) when the extra digit is a 5. [2] Unless that would run you over 18 digits. Why 18, I have no idea, and I'm afraid that most of the people on the original COBOL committee are no longer with us. That's obvious, it's how many BCD digits would fit in a doubleword of the 36-bit machines in use at that time. Jul 18 '05 #9

 P: n/a Paul Rubin wrote: "John Roth" writes: COBOL's default rounding policy is to truncate. It has a second rounding policy that is invoked by the keyword ROUND (surprise, eh?) However, one of the things that COBOL arithmetic has is precise control of the number of decimal places at all points in a computation[1], so if you don't like either truncation or the effects of ROUND, then you simply maintain an additional decimal place or two and do it your way.[2] Yeah, but what about the exact method of rounding, like the pre-PEP specifies 1.125 rounds down but 1.135 rounds up (or maybe it was the other way), while some other standard specifies always rounding down (or up) when the extra digit is a 5. Round-to-even-cent is quite popular (Roguewave calls it "Banker's Rounding" in the Money class of their commercial class library). So is always-round-up (again in the case in which an exact computation would end up with a half cent, or whatever other least significant unit of measure), which Roguewave calls "Plain Rounding", and the European Union specifies. If you have a type that only performs one kind of rounding, you cannot use that type for legally valid money computations in both Europe AND America (I think: I haven't been shown American laws specifying rounding approaches, have just seen that "round to even" mentioned as being usual, habitual, or popular). Alex Jul 18 '05 #10

 P: n/a "Paul Rubin" wrote in message news:7x************@ruckus.brouhaha.com... "John Roth" writes: COBOL's default rounding policy is to truncate. It has a second rounding policy that is invoked by the keyword ROUND (surprise, eh?) However, one of the things that COBOL arithmetic has is precise control of the number of decimal places at all points in a computation[1], so if you don't like either truncation or the effects of ROUND, then you simply maintain an additional decimal place or two and do it your way.[2] Yeah, but what about the exact method of rounding, like the pre-PEP specifies 1.125 rounds down but 1.135 rounds up (or maybe it was the other way), while some other standard specifies always rounding down (or up) when the extra digit is a 5. Like I said, you do it your way. That is, write the necessary COBOL code to round it the way you want. Ths is not as easy as it sounds since COBOL is completely lacking in the basic abstraction facilities such as subroutines with parameters within a single Procedure Division. John Roth Jul 18 '05 #11

 P: n/a "Alex Martelli" wrote in message news:dY*******************@news1.tin.it... Paul Rubin wrote: "John Roth" writes: COBOL's default rounding policy is to truncate. It has a second rounding policy that is invoked by the keyword ROUND (surprise, eh?) However, one of the things that COBOL arithmetic has is precise control of the number of decimal places at all points in a computation[1], so if you don't like either truncation or the effects of ROUND, then you simply maintain an additional decimal place or two and do it your way.[2] Yeah, but what about the exact method of rounding, like the pre-PEP specifies 1.125 rounds down but 1.135 rounds up (or maybe it was the other way), while some other standard specifies always rounding down (or up) when the extra digit is a 5. Round-to-even-cent is quite popular (Roguewave calls it "Banker's Rounding" in the Money class of their commercial class library). So is always-round-up (again in the case in which an exact computation would end up with a half cent, or whatever other least significant unit of measure), which Roguewave calls "Plain Rounding", and the European Union specifies. If you have a type that only performs one kind of rounding, you cannot use that type for legally valid money computations in both Europe AND America (I think: I haven't been shown American laws specifying rounding approaches, have just seen that "round to even" mentioned as being usual, habitual, or popular). I don't think there is any consistent law covering the matter in the US. I do know that lots of taxes come with their own tables, calculated to the penny, and don't come with directives on how to calculate them for yourselves. John Roth Alex Jul 18 '05 #12

 P: n/a Jegenye 2001 Bt wrote: Ok, I'm not the accountant type. :D I'm an ex-physicist. ;) That's why I find controlled error bounds important. But would you be happy if your bank statement reassured you that your balance is "somewhere between 708.97 and 709.12 Euros"...?-) Alex Jul 18 '05 #13

 P: n/a "John Roth" writes: Like I said, you do it your way. That is, write the necessary COBOL code to round it the way you want. Ths is not as easy as it sounds since COBOL is completely lacking in the basic abstraction facilities such as subroutines with parameters within a single Procedure Division. That's bizarre, is it really done like that in the actual real world?! I thought Cobol had built-in arithmetic, like "add gin to vermouth giving martini". Does it have "operator overloading", so that the add statement acts differently depending on how you've implemented rounding? Jul 18 '05 #14

 P: n/a Paul Rubin wrote: Alex Martelli writes: > 1. I've seen lots of strange rounding policies in various nooks > and crannies. Is there any way of specifying a rounding policy > that would be used and inherited by the result money object? Amen, Hallelujah. I've followed up to Batista's similar post to python-dev by pointing out chapter and verse of EU regulations that _mandate_ "rounding to nearest and always round exactly-halfway UPWARDS", for example. Are you serious about this? I thought financial computations with decimal arithmetic had been done in Cobol since the 1950's. They They have (at least since the early '60s -- not sure when Cobol was first released) but the accountants have not necessarily been happy with their treatment of cents. haven't gotten this stuff figured out by now? Can you crunch some calculation through a Cobol program and get an answer thtat's correct in the US and wrong in the EU? Definitely, given that the US and EU have different laws: if your program gives the same answers in both places, cases can surely be found where the answer is wrong (and at least in the EU case illegal; I don't know if the matter is regulated by law in the US) in at least one of the two places. Until and unless somebody bangs EU and US legislators' heads together, and forces them to agree on one common standard for accounting (down to such details as how to round half cents), I don't see what programmers, as such, can do about it -- except keep their software customizable in such variant-by-jurisdiction respects:-(. Alex Jul 18 '05 #15

 P: n/a Paul Rubin wrote: "John Roth" writes: Like I said, you do it your way. That is, write the necessary COBOL code to round it the way you want. Ths is not as easy as it sounds since COBOL is completely lacking in the basic abstraction facilities such as subroutines with parameters within a single Procedure Division. That's bizarre, is it really done like that in the actual real world?! I thought Cobol had built-in arithmetic, like "add gin to vermouth giving martini". Does it have "operator overloading", so that the add statement acts differently depending on how you've implemented rounding? No (no overloading). But comparing Cobol's arithmetic to a mistaken belief that a decent Martini cocktail is somehow automatically obtained by "adding gin to vermouth" IS quite an apt simile (there's about six bars here in Bologna I can count on to serve decent Martini cocktails: the other hundreds of bars subscribe to the "Cobol arithmetic" approach:-). Alex Jul 18 '05 #16

 P: n/a John Roth fed this fish to the penguins on Saturday 18 October 2003 08:51 am: [2] Unless that would run you over 18 digits. Why 18, I have no idea, and I'm afraid that most of the people on the original COBOL committee are no longer with us. Is that 18 /after/ the decimal, or 18 in total? I recall that my college machine had hardware for BCD arithmetic (that board failed one term -- FORTRAN classes were not affected as the integer and float ALUs were still working, but COBOL classes were quite late on assignments). The BCD unit used four normal registers to hold a value -- 16 bytes. 16 bytes supported a 32 digit BCD number (actually, I think it was 31 digits and a marker for sign/decimal place; as I recall, the sign position floated as needed for the data). -- ================================================== ============ < wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG < wu******@dm.net | Bestiaria Support Staff < ================================================== ============ < Bestiaria Home Page: http://www.beastie.dm.net/ < Home Page: http://www.dm.net/~wulfraed/ < Jul 18 '05 #18

 P: n/a Alex Martelli fed this fish to the penguins on Saturday 18 October 2003 11:11 am: They have (at least since the early '60s -- not sure when Cobol was first released) but the accountants have not necessarily been happy with their treatment of cents. My memory is failing, but I think FORTRAN predates COBOL by a few years... I think CODASYL got the first COBOL spec out around 1961. The language was standardized around 68 (74, 85, 2000?) Until and unless somebody bangs EU and US legislators' heads together, and forces them to agree on one common standard for accounting (down to such details as how to round half cents), I don't see what programmers, as such, can do about it -- except keep their software customizable in such variant-by-jurisdiction respects:-(. I'd suspect the safest method would be to keep the data internally one or two decimal places beyond that needed for the most precise currency expected, and perform locale specific rounding only when reporting values. (Something I suspect the Lockheed payroll system has to do, as my current annual rate is 100,866.000000 [yes, the paycheck stub lists 6 decimal places!], which works out to an hourly rate of 48.493269xxx -- if they'd rounded the latter before calculating the paycheck I'd be cheated out of nearly $7 a year. Does make it painful to track in Quicken -- every week a different gross pay or tax deduction appears as the "error" for each item reaches the rounding "roll-over" point) -- ================================================== ============ < wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG < wu******@dm.net | Bestiaria Support Staff < ================================================== ============ < Bestiaria Home Page: http://www.beastie.dm.net/ < Home Page: http://www.dm.net/~wulfraed/ < Jul 18 '05 #21  P: n/a John Roth fed this fish to the penguins on Saturday 18 October 2003 11:55 am: One of the few benefits of static typing is that type declarations can include things like precision (part of COBOL and PL/1) and rounding policy (which is not part of either language.) COBOL does have the ROUNDED keyword, though that isn't part of the declaration, but of the usage: add gin to vermouth giving martini {truncates} add gin to vermouth giving martini rounded {rounds, somehow} -- ================================================== ============ < wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG < wu******@dm.net | Bestiaria Support Staff < ================================================== ============ < Bestiaria Home Page: http://www.beastie.dm.net/ < Home Page: http://www.dm.net/~wulfraed/ < Jul 18 '05 #22  P: n/a Dennis Lee Bieber fed this fish to the penguins on Saturday 18 October 2003 12:31 pm: needed unless martini had been declared as a ROUNDED field, in which Whoops, my first time through the book I thought ROUNDED applied to the field declaration, not to any specific operation... it goes on the math operation after naming the receiving field... -- ================================================== ============ < wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG < wu******@dm.net | Bestiaria Support Staff < ================================================== ============ < Bestiaria Home Page: http://www.beastie.dm.net/ < Home Page: http://www.dm.net/~wulfraed/ < Jul 18 '05 #23  P: n/a "Dennis Lee Bieber" wrote in message news:l5************@beastie.ix.netcom.com... Alex Martelli fed this fish to the penguins on Saturday 18 October 2003 11:11 am: They have (at least since the early '60s -- not sure when Cobol was first released) but the accountants have not necessarily been happy with their treatment of cents. My memory is failing, but I think FORTRAN predates COBOL by a few years... I think CODASYL got the first COBOL spec out around 1961. The language was standardized around 68 (74, 85, 2000?) Until and unless somebody bangs EU and US legislators' heads together, and forces them to agree on one common standard for accounting (down to such details as how to round half cents), I don't see what programmers, as such, can do about it -- except keep their software customizable in such variant-by-jurisdiction respects:-(. I'd suspect the safest method would be to keep the data internally one or two decimal places beyond that needed for the most precise currency expected, and perform locale specific rounding only when reporting values. (Something I suspect the Lockheed payroll system has to do, as my current annual rate is 100,866.000000 [yes, the paycheck stub lists 6 decimal places!], which works out to an hourly rate of 48.493269xxx -- if they'd rounded the latter before calculating the paycheck I'd be cheated out of nearly$7 a year. Does make it painful to track in Quicken -- every week a different gross pay or tax deduction appears as the "error" for each item reaches the rounding "roll-over" point) Sometimes that's also a result of union negotions and interesting policies to avoid losing cents to rounding errors. One way of handling all of this is to always calcualte YTD and then subtract the prior YTD to get current. Then there are interesting strategies to allocate the cents to the workers on alternate weeks so that nobody files a union grievance... John Roth -- > ================================================== ============ < > wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG < > wu******@dm.net | Bestiaria Support Staff < > ================================================== ============ < > Bestiaria Home Page: http://www.beastie.dm.net/ < > Home Page: http://www.dm.net/~wulfraed/ < Jul 18 '05 #24
 P: n/a Alex Martelli wrote in message news:tb***********************@news2.tin.it... Jegenye 2001 Bt wrote: But would you be happy if your bank statement reassured you that your balance is "somewhere between 708.97 and 709.12 Euros"...?-) No, I'd be absolutely happy if the bank statement would contain that the balance is 11101223.43* and this amount was computed by the publicly known and standardized error propagation rules, so the bank assures me the number cannot be less than 11101222.87 and it cannot be more than 11101223.98 due to rounding numbers according to those rules. * let's speak of a much nicer sum of money than that if it's about my hypotetical bank account :-) I know this is wishful thinking and even the bank employees would be dazzled. ;( Once I tried to explain to a gov. official that it doesn't matter at all if unemployment is 15.1% or 14.9% in a certain region when he asked what that $\sigma = 0.1%$ means next to 15% ... You cannot tell the real value only that it's between those values with such and such probability. Ok, he understands. But is unemployment high or low in that region according to law? (Which stated that regions with enemployment higher than , say, 15% are entitled to certain funds..) This world is NOT the best world of all the possible worlds, Mr. Leibnitz. ;) Cheers, Miklós -- PRISZNYÁK Miklós --- Jegenye 2001 Bt. ( mailto:je*********@parkhosting.com ) Egyedi szoftverkészítés, tanácsadás Custom software development, consulting http://jegenye2001.parkhosting.com Alex Jul 18 '05 #25