[boost] Re: Thoughts on fixdec
Fernando Cacciola wrote: I'm inclined toward boost::numeric. Two votes for boost::numeric. I prefer just 'decimal' because most decimal numbers I know of are fixed-point. So I think 'fixed' can be left implicit. Two votes (including mine) for decimal; two votes (including Michel Andre's from a while back) for fixed_decimal. Couldn't [overflow/underflow checks] be provided as a postcondition, in terms of BOOST_ASSERT? I'll consider that. Fernando: Me: Daryle: 6. There should only be conversions from strings, and _no_ mixed operations with strings. In the absence of decimal literals, I think it's easier for the user to be able to use strings as pseudo-literals in all contexts; and I don't see how the mixed operations do any harm. The problem is that quite unfortunately, string literals are just pointers to constant char, but such pointers are also used to access raw memory, so, char const* is the target to implicit conversions from a lot more than string literals. This would lead to unexpected implicit conversions. But I think that C++ inherits that part of the spirit of C that says, Trust the programmer. It's not that all programmers are trustworthy, nor even that some programmers are always trustworthy. It's that many programmers become increasingly trustworthy as they gain more experience; and we want to reward that behavior. 8-) Fernando: Me: Daryle: 13. You have strange (regular) assignment semantics. You try to change the receiver's logical value to the source's logical value, but retain the receiver's original scale (internally shifting the new significand and doing any rounding if needed). ... you will get strange effects if you try to change containers of decimal through assignment. I thought it would be less surprising if a decimal object's scale were immutable. This matches prior art (the BCD type on IBM mainframes, for example) in which the scale is part of the type. You're right about containerdecimal; but remember that this class isn't intended for number-crunching; so I don't really care about assigning matrices, etc. But this isn't about assigning matrices and number-crunching, it's about C++ assignment semantics. The postcondition of equivalence for assignment is a strongly fundamental feature of the C++ object model, and everything and everyone, not just containers, relies on that. Hmm... I came up with two use cases: figuring the final payment of a loan and converting currency. In both cases, I had to write the code very carefully to /create/ the error I was worried about; and even after doing so, neither case was particularly compelling. You might have convinced me. Also, when considering the case of converting currencies, I saw a problem with multiplication not being commutative: decimal dollars(2, 314.75); decimal exchange_rate(6, 0.890004); decimal euros(2); #if ONE_WAY_TO_DO_IT euros [round_up]= exchange_rate * dollars; #else euros = dollars [round_up]* exchange_rate; #endif Programmers would have to be very careful with such code in any event; so maybe my argument isn't a good one. I still have an /emotional/ attachment to it, though. I'll work on that. 8-) Question: should I go back to templateint Scale class decimal? Advantages: The assignment semantics issue goes away because the scale is part of the type. It's more like prior art. Disadvantages: The scale must be a constant expression. There are member template issues with some compilers. It won't work at all with MSVC v5 which can't deduce non-type template arguments. (OK, I could bite the bullet and maintain a non-Boost version for my own use at work; but I wouldn't be happy about it.) --Bill Seymour ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[boost] Re: Thoughts on fixdec
Daryle Walker wrote: I think this library should be accepted. Thanks. 1.We have two math-related namespaces already. The boost::math namespace leans to theoretical work and boost::numeric leans to hard-core computation. I don't know that there's anything particularly theoretical about decimal representations; and the library's target audience is not those users who do hard-code computation, which I understand to mean numerical programming (in the sense of scientific and statical programming). It's not a major issue for me; and I'll do whatever the majority wants. You should probably pick one of those namespaces (numeric?) and possibly rename the class to fixed_decimal. I'm reticent to require the user to type the extra fixed_ in every declaration of such an object. 2.There is a boost/limits.hpp header to give deficient systems the std::numeric_limits class template (and pass through if limits exists). I had that in a previous version but wasn't satisfied with it. I can't remember why; so I'll look at the old code and see what it was that I didn't like. 3.Instead of playing around with determining the significand type, just #include boost/cstdint.hpp, ... I do. ... use boost::intmax_t and be done with it. You're right. My mind got stuck on int_least64_t; and I completely forgot about intmax_t. Also, that might solve the boost/limits.hpp problem (whatever that was) if numeric_limitsintmax_t::is_specialized and numeric_limitsintmax_t::digits10 is a constant expression. I'll check that out. 4.What, no (safe-)Boolean conversion? Ack! You're right! 5.The conversion from int needs to check for overflow. The conversion from double needs to check also for underflow. The conversion from strings needs to check also for bad formats. But that would require some users to pay for something they don't need. Users who need that level of correctness can write their own checks; and others (probably most of the library's target audience) get better efficiency. 6.There should only be conversions from strings, and _no_ mixed operations with strings. In the absence of decimal literals, I think it's easier for the user to be able to use strings as pseudo-literals in all contexts; and I don't see how the mixed operations do any harm. In particular, I'm willing to give the user credit for knowing that my_decimal += The quick brown fox...; doesn't make any sense. 7.Does the scale need to be first in all constructors? If it can be placed second, then converting constructors can be made and most of the mixed operator functions can go away. [ctor examples] I'd want to see use cases for all those conversions before I agreed to add them. Remember, the library's target audience is folk who are writing financial software. It's not intended as a general- purpose number-crunching library. 8.The round_down and round_up functions don't seem clear enough. They're intended to be clear to accountants who deal only with non-negative debits and non-negative credits; and whether a value is a debit or a credit is orthogonal to the mathematical notion of sign. Remember the instructions on your tax return form that tell you, if line x is less than line y, subtract line x from line y and write the answer over here; otherwise subtract line y from line x and write the answer over there? Sure, that's a howler for mathematicians; but it makes perfect sense to accountants. 8-) 9.What, no operator nor operator ? (The shift would be a power of ten.) Those operators don't exist for the floating-point types, and with good reason IMO. Their use is best reserved for twiddling bits, not for scaling. Even for binary integers, i 1 is not generally the same thing as i * 2 except on 2's-complement boxes. 10. The class is no longer a template, but some of the wording in the code and docs act like it's still a template. (When you're rewording, there's some HTML errors to fix.) Could you point them out? 11. ... ... class MyNum { public: //... bool is_negative() const; //... }; ... would save time over doing a (possible) conversion from zero and a comparison. But (my_decimal 0) doesn't do a conversion; and it lets the user use decimals the way they would use other arithmetic types. 12. [use pword to save rounding mode I/O state] Yes, much better. I'll play with that. 13. You have strange (regular) assignment semantics. You try to change the receiver's logical value to the source's logical value, but retain the receiver's original scale (internally shifting the new significand and doing any rounding if needed). ... you will get strange effects if you try to change containers of decimal through assignment. I thought it would be less surprising if a decimal object's scale were immutable. This matches prior art (the BCD type on IBM mainframes, for example) in which
RE: [boost] Re: Thoughts on fixdec
Title: RE: [boost] Re: Thoughts on fixdec 6. There should only be conversions from strings, and _no_ mixed operations with strings. In the absence of decimal literals, I think it's easier for the user to be able to use strings as pseudo-literals in all contexts; and I don't see how the mixed operations do any harm. In particular, I'm willing to give the user credit for knowing that my_decimal += The quick brown fox...; doesn't make any sense. I don't have an opinion, but one other case that I've seen from people use to using std::string is: string error = The number + my_decimal + is too big; Glen -Original Message- From: Bill Seymour To: [EMAIL PROTECTED] Sent: 7/16/03 5:55 AM Subject: [boost] Re: Thoughts on fixdec Daryle Walker wrote: I think this library should be accepted. Thanks. 1. We have two math-related namespaces already. The boost::math namespace leans to theoretical work and boost::numeric leans to hard-core computation. I don't know that there's anything particularly theoretical about decimal representations; and the library's target audience is not those users who do hard-code computation, which I understand to mean numerical programming (in the sense of scientific and statical programming). It's not a major issue for me; and I'll do whatever the majority wants. You should probably pick one of those namespaces (numeric?) and possibly rename the class to fixed_decimal. I'm reticent to require the user to type the extra fixed_ in every declaration of such an object. 2. There is a boost/limits.hpp header to give deficient systems the std::numeric_limits class template (and pass through if limits exists). I had that in a previous version but wasn't satisfied with it. I can't remember why; so I'll look at the old code and see what it was that I didn't like. 3. Instead of playing around with determining the significand type, just #include boost/cstdint.hpp, ... I do. ... use boost::intmax_t and be done with it. You're right. My mind got stuck on int_least64_t; and I completely forgot about intmax_t. Also, that might solve the boost/limits.hpp problem (whatever that was) if numeric_limitsintmax_t::is_specialized and numeric_limitsintmax_t::digits10 is a constant _expression_. I'll check that out. 4. What, no (safe-)Boolean conversion? Ack! You're right! 5. The conversion from int needs to check for overflow. The conversion from double needs to check also for underflow. The conversion from strings needs to check also for bad formats. But that would require some users to pay for something they don't need. Users who need that level of correctness can write their own checks; and others (probably most of the library's target audience) get better efficiency. 6. There should only be conversions from strings, and _no_ mixed operations with strings. In the absence of decimal literals, I think it's easier for the user to be able to use strings as pseudo-literals in all contexts; and I don't see how the mixed operations do any harm. In particular, I'm willing to give the user credit for knowing that my_decimal += The quick brown fox...; doesn't make any sense. 7. Does the scale need to be first in all constructors? If it can be placed second, then converting constructors can be made and most of the mixed operator functions can go away. [ctor examples] I'd want to see use cases for all those conversions before I agreed to add them. Remember, the library's target audience is folk who are writing financial software. It's not intended as a general- purpose number-crunching library. 8. The round_down and round_up functions don't seem clear enough. They're intended to be clear to accountants who deal only with non-negative debits and non-negative credits; and whether a value is a debit or a credit is orthogonal to the mathematical notion of sign. Remember the instructions on your tax return form that tell you, if line x is less than line y, subtract line x from line y and write the answer over here; otherwise subtract line y from line x and write the answer over there? Sure, that's a howler for mathematicians; but it makes perfect sense to accountants. 8-) 9. What, no operator nor operator ? (The shift would be a power of ten.) Those operators don't exist for the floating-point types, and with good reason IMO. Their use is best reserved for twiddling bits, not for scaling. Even for binary integers, i 1 is not generally the same thing as i * 2 except on 2's-complement boxes. 10. The class is no longer a template, but some of the wording in the code and docs act like it's still a template. (When you're rewording, there's some HTML errors to fix.) Could you point them out? 11. ... ... class MyNum { public: //... bool is_negative() const; //... }; ... would save time over doing a (possible) conversion from zero and a comparison
[boost] Re: Thoughts on fixdec
Bill Seymour [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] Daryle Walker wrote: (Yes, I know that some numeric purists [and GCC] hate long double, but I want to maximize the capabilities.) The problem with a 'long double' ctor, either with or without 'double' ctor, is that long double is never the target of floating-point promotions, so decimal construction would become ambiguous from some types. 1. We have two math-related namespaces already. The boost::math namespace leans to theoretical work and boost::numeric leans to hard-core computation. I don't know that there's anything particularly theoretical about decimal representations; and the library's target audience is not those users who do hard-code computation, which I understand to mean numerical programming (in the sense of scientific and statical programming). It's not a major issue for me; and I'll do whatever the majority wants. I'm inclined toward boost::numeric. You should probably pick one of those namespaces (numeric?) and possibly rename the class to fixed_decimal. I'm reticent to require the user to type the extra fixed_ in every declaration of such an object. I prefer just 'decimal' because most decimal numbers I know of are fixed-point. So I think 'fixed' can be left implicit. 5. The conversion from int needs to check for overflow. The conversion from double needs to check also for underflow. The conversion from strings needs to check also for bad formats. But that would require some users to pay for something they don't need. Users who need that level of correctness can write their own checks; and others (probably most of the library's target audience) get better efficiency. Couldn't this be provided as a postcondition, in terms of BOOST_ASSERT? 6. There should only be conversions from strings, and _no_ mixed operations with strings. In the absence of decimal literals, I think it's easier for the user to be able to use strings as pseudo-literals in all contexts; and I don't see how the mixed operations do any harm. The problem is that quite unfortunately, string literals are just pointers to constant char, but such pointers are also used to access raw memory, so, char const* is the target to implicit conversions from a lot more than string literals. This would lead to unexpected implicit conversions. 9. What, no operator nor operator ? (The shift would be a power of ten.) Those operators don't exist for the floating-point types, and with good reason IMO. Their use is best reserved for twiddling bits, not for scaling. Even for binary integers, i 1 is not generally the same thing as i * 2 except on 2's-complement boxes. I agree. 13. You have strange (regular) assignment semantics. You try to change the receiver's logical value to the source's logical value, but retain the receiver's original scale (internally shifting the new significand and doing any rounding if needed). ... you will get strange effects if you try to change containers of decimal through assignment. I thought it would be less surprising if a decimal object's scale were immutable. This matches prior art (the BCD type on IBM mainframes, for example) in which the scale is part of the type. You're right about containerdecimal; but remember that this class isn't intended for number-crunching; so I don't really care about assigning matrices, etc. But this isn't about assigning matrices and number-crunching, it's about C++ assignment semantics. The postcondition of equivalence for assignment is a strongly fundamental feature of the C++ object model, and everything and everyone, not just containers, relies on that. No class, specially a class modeling a number, should violate that. You can use something of the form x[keep_scale]=y; for that special semantics. Fernando Cacciola ___ Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost