to_long() of an imaginary unit is 9
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.
Hi Vitaly, On 14.04.21 13:55, Vitaly Magerya wrote:
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.
Hmm, the manual also says that 'to_int()' and 'to_long()' only work when the number they are applied on is an exact integer. You should do explicit checking.
... I'm guessing this is not the expected behavior.
According to this comment here <https://www.ginac.de/reference/classGiNaC_1_1numeric.html#ad8c883c872e06a3573271940f05e4bf1> it is intended.
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.
Sorry, the constants are hard-wired in parser/parser.cpp. -richy. -- Richard B. Kreckel <https://in.terlu.de/~kreckel/>
participants (2)
-
Richard B. Kreckel
-
Vitaly Magerya