[boost] Re: Thoughts on fixdec

2003-07-17 Thread Bill Seymour
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

2003-07-16 Thread Bill Seymour
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

2003-07-16 Thread Glen Knowles
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

2003-07-16 Thread Fernando Cacciola

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