Hi, On Sun, 19 Jan 2014, Richard B. Kreckel wrote:
I see: If one of the x_ is ±1+0.0*I, then it should be assumed to be ±1. As discussed, this would go against the principles of CLN. But those principles are not GiNaC's which simplifies 2.0*x-x-x to 0, not to 0.0*x.
This just makes me wonder if the elimination of a floating-point zero imaginary part would make a useful transformation of class numeric.
I'm not sure if we should do this. We have in GiNaC also the opposite case, namely that a floating 0.0 is not transformed into 0, as the following code fragment shows: ex t1 = numeric("2.1"); ex t3 = t1-t1; if ( (t3 == 0) && !ex_to<numeric>(t3).is_rational() ) std::cout << "equal to zero, but not rational" << std::endl; The core of the problem are two different philosophies, what a floating point number should be. These two philosophies are: 1. A floating point number represents an intervall, whose size depends on Digits. 2. A floating point number is a rational number, which is the closest approximation within Digits to the number we want. The GinaC class numeric is basically a wrapper around CLN, so this is a CLN-issue. In my opinion CLN is not strict in implementing one or the other philosophy. This can be seen by looking at the GiNaC-operators is_real() and ==, which boil down to the CLN methods instanceof(..., cln::cl_R_ring) and equal(...,...). As we have discussed, 1+0.0*I is not considered to be real, and thus an example of philosophy 1. On the other hand, comparing a float to an exact number as in 1+0.0*I==1, the float is converted to a rational number and compared (the details can be found in cln-1.3.3/src/real/elem/cl_R_equal.cc). This is basically philosophy 2. However, I would not argue to change this. CLN is a well-established library, and changing one of these operators might break other third-party programs. Besides, the manual of CLN is quite clear what these operators do. For GiNaC the documentation is not as precise, but this can be improved. Therefore my suggestions are: - a small correction to the manual (taking Alexei's comment into account) - a patch to inifcns_nstdsums.cpp (in order to please Alexei I have inserted some extra {...}, however the modification should be in Li_eval, there one knows that the arguments are actually +/-1, in zeta2_eval the only sensible thing to do would be to call hold(), which is not what we want.) A testcase is probably not so helpful, as it can only check for the re-introduction of the bug in the same place. It is more likely that the same bug (or should I say the same feature) in different disguise will hit us somewhere else. I have some hope that we can close this thread. Best wishes, Stefan