The header file convert.H
supplies several conversion functions.
They are for converting a numerical value of one type into another
numerical type (at least one of the types must be a CoCoALib
type). There is also a way of safely converting machine integer
values into other integral types.
There are two families of conversion functions:
ConvertTo<DestType>(src)
the result is the converted value; if src
cannot
be converted then an error is thrown (with code ERR::BadConvert
)
ConvertTo<DestType>(src, ErrMesg)
the result is the converted
value; if src
cannot be converted then an error is thrown
(with code ErrMesg
typically created by calling ``ErrorInfo(ERR::code, "fn name"))
IsConvertible(dest,src)
the result is a boolean: true
means the conversion
was successful (and the result was placed in dest
, the 1st arg)
Here is a summary of the conversions currently offered:
"to" type | "from" type | notes |
---|---|---|
(unsigned) long | BigInt |
|
(unsigned) int | BigInt |
|
(unsigned) long | BigRat |
|
(unsigned) int | BigRat |
|
long | RingElem |
equiv to IsInteger & range check |
BigInt |
RingElem |
same as IsInteger |
BigRat |
RingElem |
same as IsRational |
long | double | value must be integral & in range |
BigInt |
double | |
BigRat |
double | |
double | BigInt |
may have rounding error!! |
double | BigRat |
may have rounding error!! |
NOTE 1: Conversion to a string
can be achieved via ostringstream
:
ostringstream buffer; buffer << value; const string& ConvertedValue = buffer.str();
NOTE 2: Conversion fails if overflow occurs. Currently converting a non-zero BigRat
to
a double
does not fail if the closest double is 0.
There is a templated class called NumericCast
; it is roughly analogous
to BOOST::numeric_cast
, and will eventually be replaced by direct use
of this BOOST feature. It is to be used for converting safely from one
machine integer type to another: the conversion succeeds only if the value
supplied can be represented by the destination type. In case of failure an
ERR::BadConvert
exception is thrown.
The ConvertTo
fns simply call the corresponding IsConvertible
function -- indeed a template implementation is appropriate here.
Only some combinations of IsConvertible
functions are present so far.
The class NumericCast
has a single template argument, and the constructor
has a separate template argument to allow the "natural syntax" like that of
static_cast
(or BOOST's numeric_cast
). I used a class rather than a templated function because a
function would have required the user to specify two template arguments
(i.e. unnatural syntax). I don't know if this is the best way to achieve
what I want, but it is simple enough that there are obviously no deficiencies.
Conversion to C++ integral types other than (unsigned) int/long is not yet supported.
Indeed the IsConvertible
functions are a hotch potch, but how can it be done better?
BOOST has numeric_cast
which is like NumericCast
for built in numerical types.
Sooner or later we should use that.
Should conversion of BigRat
to double
ignore underflow, or should it fail?