[GiNaC-list] to_long() of an imaginary unit is 9

Vitaly Magerya vmagerya at gmail.com
Wed Apr 14 13:55:44 CEST 2021


Hi, all. It seems that numeric conversion routines like to_long()
don't check for imaginary numbers, and happily return random
results. Here's an example program:


    #include <ginac/ginac.h>
    #include <ginac/parser.h>
    #include <fstream>
    #include <sstream>

    using namespace std;
    using namespace GiNaC;

    int
    main()
    {
        parser reader;
        istringstream ifs("I");
        ex expr = reader(ifs);
        if (is_a<numeric>(expr)) {
            numeric x = ex_to<numeric>(expr);
            cout << "Numeric: " << x << "\n";
            cout << ".real(): " << x.real() << "\n";
            cout << ".imag(): " << x.imag() << "\n";
            cout << ".numer(): " << x.numer() << "\n";
            cout << ".denom(): " << x.denom() << "\n";
            cout << ".numer().to_long(): " << x.numer().to_long() << "\n";
            cout << ".denom().to_long(): " << x.denom().to_long() << "\n";
            cout << ".to_long(): " << x.to_long() << "\n";
        } else {
            cout << "Not numeric: " << expr << "\n";
        }
    }

The result of it with GiNaC 1.7.8 (CLN 1.3.6) is:

    $ c++ -o example example.cpp -lginac -lcln && ./example
    Numeric: I
    .real(): 0
    .imag(): 1
    .numer(): I
    .denom(): 1
    .numer().to_long(): 9
    .denom().to_long(): 1
    .to_long(): 9

Seeing that the documentation contains this phrase:

    Both to_int()/to_long() and to_double() discard the imaginary
    part of complex numbers.

... I'm guessing this is not the expected behavior.

* * *

As a related question, is there any way to prevent parser from
interpreting "I" as an imaginary unit? I'd like it to be just a variable.


More information about the GiNaC-list mailing list