[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: CLN



On Sun, Feb 13, 2000 at 06:45:55PM +0100, Richard B. Kreckel wrote:
> Hello,
> 
> George wrote:
> > I'm too lazy to find the CLN list, so I'll ask here first.  I'm stuck with
> > the changeover because of two issues
> 
> Not every project has a list.    ;-)
> 
> > 1) It's impossible with the defined interface (as I understand it) to figure
> > out if a cl_R is actually an exact number, or if it is an integer in fact.  I
> > copied some things from internal CLN headers such as integerp and rationalp
> > but I guess that's wrong to do that.  What is the correct way to do this?
> 
> Since you insist on using cl_R I assume that you wish to handle
> I==sqrt(-1) youself, somehow.  That's fine.  Then, how about this:

No, actually I use cl_N as the type.  But finding out if a number is just
checking that the imagpart is other then 0.  Then I can get both the
imaginary and real part as cl_R.  I'm just stuck converting further :)

> #include <cln/cln.h>
> #include <iostream>
> 
> void checkme(ostream & os, cl_R x)
> {
>     if (instanceof(x,cl_I_ring))
>         os << x << " seems to be an integer" << endl;
>     if (instanceof(x,cl_RA_ring))
>         os << x << " seems to be a rational" << endl;
> }

aha ok, that sounds good.

> int main()
> {
>     cl_R n1(2);
>     cl_R gamma(".5772156649015328606065120900824024310421593359399235988057672348848677267776646709369470632917467495");
>     cl_R n2 = n1 / 3;
>     checkme(cout, n1);
>     checkme(cout, gamma);
>     checkme(cout, n2);
> }
> 
> It will return:
> 2 seems to be an integer
> 2 seems to be a rational
> 2/3 seems to be a rational
> 
> Since you didn't see it in the manual: Are you sure you aren't using an
> old version?  instanceof() was introduced rather late, you should use at
> least 1.0.2.

I'm using 1.0.3.  I must have missed it in the manual, THANKS!

> > 2) how do I get a native type out of a cl_R?  I know something is an integer
> > and that it will fit in an integer, but I can't get it.  I will need to do
> > the same for doubles.
> 
> On the above defined constants, do:
> 
>     cout << cl_double_approx(n1) << endl;
>     cout << cl_double_approx(gamma) << endl;
>     cout << cl_double_approx(n2) << endl;
>     cout << cl_I_to_int(The(cl_I)(n1)) << endl;
> 
> Note that for cl_I_to_int you first have to check if it's an integer
> because otherwise The()() will bomb out (as documented).  If you want to
> implement something along these lines in your own program, maybe you 
> should have a look at class GiNaC::numeric in file ginac/numeric.cpp from
> the obvious package.  It implements a wrapper around class cl_N suitable
> for a CAS.

I'll take a look at that.  I'm still a C programmer at the core, so I'm
trying to use as much C semantics as possible and to compile as few files
with C++ as possible.  I tried in fact to write a wrapper around cl_N but
gave up.  It wouldn't allow me to inline in eval.c (which thus became
eval.cc:( )

> And later he wrote:
> > Well a third issue, the current printing methods print to a C++ stream, so if
> > I need a string I guess I might needs some weird stream hacks or does C++
> > allow me to make a simple stream that is in fact a string?
> 
> #include <sstream> is what you really want to do.  Unfortunately, it is
> not available as of gcc-2.95.2 and doesn't seem to come into gcc-2.96.
> You need to use libstdc++-v3 to get this functionality (I haven't tried
> it though).  Go to <http://sourceware.cygnus.com/libstdc++/>.  It's in the
> standard.

Uh ... That's bad though.  I don't want to require yet not widely used
libraries.  So it will probably come to ugly hacks :)

George