Hi All: I don't know if I'm wrong, but why are not defined elsewhere cln::operator-(const float , const cln::cl_R&) and some with double, etc. to compile this silly program. #include <cln/real.h> int main(int argc, char **argv) { cln::cl_F a,b; a=1; b=1.0-a; } -- *************************************************************************** * Dr. Isidro Cachadiña Gutiérrez * * Departamento de Física * * Facultad de Ciencias * * Universidad de Extremadura * * 06071 Badajoz ( SPAIN ) * * email: icacha@unex.es * * Teléfono: +34 924 289 300 Ext. 6826 Fax: +34 924 289 651 * *************************************************************************** * Usuario Linux: 8569 * * Para clave pública GnuPG: http://onsager.unex.es/firma.pub.asc * ***************************************************************************
On Fri, 19 Nov 2004, Isidro [iso-8859-15] Cachadiña Gutiérrez wrote:
I don't know if I'm wrong, but why are not defined elsewhere
cln::operator-(const float , const cln::cl_R&)
and some with double, etc. to compile this silly program.
#include <cln/real.h> int main(int argc, char **argv) { cln::cl_F a,b; a=1; b=1.0-a; }
Hmm, good question. Did you notice that b=1-a works because there is oerator-(int, const cl_F&)? So, this looks like an omission to me. I'm just wondering if it wouldn't be better to templatize the fallthrough case after all the special integer inline helpers, like this: template< typename T > inline const cl_F operator+ (const T& x, const cl_F& y) { return cl_F(x) + y; } and so on. That should match anything that can be converted to cl_F, then, in particular double and float. I'm also wondering whether that would be safe enough: maybe one could apply some cute traits-trick? Or maybe one shouldn't try to be clever and just write down the operators in a straightfoward way since there are only two interesting cases? Buena noche -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/>
On Sat, 20 Nov 2004, Richard B. Kreckel wrote:
On Fri, 19 Nov 2004, Isidro [iso-8859-15] Cachadiña Gutiérrez wrote:
I don't know if I'm wrong, but why are not defined elsewhere
cln::operator-(const float , const cln::cl_R&)
and some with double, etc. to compile this silly program.
#include <cln/real.h> int main(int argc, char **argv) { cln::cl_F a,b; a=1; b=1.0-a; }
Hmm, good question. Did you notice that b=1-a works because there is oerator-(int, const cl_F&)? So, this looks like an omission to me. I'm just wondering if it wouldn't be better to templatize the fallthrough case after all the special integer inline helpers, like this:
template< typename T > inline const cl_F operator+ (const T& x, const cl_F& y) { return cl_F(x) + y; }
and so on. That should match anything that can be converted to cl_F, then, in particular double and float. I'm also wondering whether that would be safe enough: maybe one could apply some cute traits-trick? Or maybe one shouldn't try to be clever and just write down the operators in a straightfoward way since there are only two interesting cases?
Actually, the situation is more involved. This is due to CLN's type system, automatic conversions and all that syntactic sugar of overloading operator@, where @ stands for `+', `-', `*' or `/'. *) First, you dodged the question of the return type. What should cln::operator@(float, const cln::cl_R&) return? Is it just to conveniently save a few keystrokes and should hence return a cln::cl_R? No, wait! cln::cl_R can have arbitrary precision but we do know the resulting precision cannot be better than that of float or double, respectively. It would be wrong to return anything other than cl_FF or cl_DF; why return a base type? Okay, that'ld leave us with implementing: inline const cl_FF operator@ (const cl_R& x, const float y) { return float_approx(x) @ y; } inline const cl_FF operator@ (const float x, const cl_R& y) { return x @ float_approx(y); } and the same for double. And possibly for cl_F due to efficiency concerns. In any case, that operator@ can hardly be said to be an operation in cl_R any more, because it always reduces its arguments precision-wise and does so even by declaration! This is why I am reluctant about such operators. If a user wants his nice 1000 digit precision computation to decay he should be forced to state so explicitly. Second, there are two cages in CLN's type zoo where the helper operator+ you propose would make perfect sense. The beasts therein are cl_FF and cl_DF, where there are no doubts about the intent of: cl_DF a,b; a = 1.; b = 1. @ a; But that turns out to be not possible to write. I think that it was Bruno's intent that such code should be legal. After all, there is conversion from float/double to cl_FF/cl_DF via (non-explicit) ctors and assignment operators. The last line is actually: b.cl_DF::operator=(operator+(double,cl_DF)) and then automatic conversion from double to cl_DF should kick in and presto. However, as soon as the header <cln/dfloat.h> is mixed with <cln/float.h>, some ambiguousitis arises. The compiler tells us that it doesn't know which of these candidates to pick: const cln::cl_F cln::operator@(const cln::cl_F&, const cln::cl_F&) const cln::cl_F cln::operator@(const cln::cl_RA&, const cln::cl_F&) const cln::cl_F cln::operator@(const cln::cl_I&, const cln::cl_F&) const cln::cl_F cln::operator@(int, const cln::cl_F&) const cln::cl_F cln::operator@(unsigned int, const cln::cl_F&) const cln::cl_F cln::operator@(long int, const cln::cl_F&) const cln::cl_F cln::operator@(long unsigned int, const cln::cl_F&) const cln::cl_F cln::operator@(const cln::cl_F&, int) <near match> const cln::cl_F cln::operator@(const cln::cl_F&, unsigned int) <near match> const cln::cl_F cln::operator@(const cln::cl_F&, long int) <near match> const cln::cl_F cln::operator@(const cln::cl_F&, long unsigned int) <near match> const cln::cl_DF cln::operator@(const cln::cl_DF&, const cln::cl_DF&) Note that the one we want occurs in the last line and isn't even a near match. Unfortunately, <cln/dfloat.h> pulls in <cln/float.h> all by itself. :-( Well, then. Should we be able to write that? I take the stance that yes, we should. After all, this seems to be just a glitch where the intented conversion fails due to unforseen interferences. I've attached a patch. It hasn't received much testing. Does that patch look reasonable? Regards -richy. *) "Syntactic sugar causes cancer of the semicolon." -- Alan Perlis -- Richard B. Kreckel <http://www.ginac.de/~kreckel/>
Hi! Before anybody protests: I solemnly promise not to even try to to think again when I'm tired! On Wed, 24 Nov 2004, Richard B. Kreckel wrote: [...]
First, you dodged the question of the return type. What should cln::operator@(float, const cln::cl_R&) return? Is it just to conveniently save a few keystrokes and should hence return a cln::cl_R? No, wait! cln::cl_R can have arbitrary precision but we do know the resulting precision cannot be better than that of float or double, respectively. It would be wrong to return anything other than cl_FF or cl_DF; why return a base type? Okay, that'ld leave us with implementing:
inline const cl_FF operator@ (const cl_R& x, const float y) { return float_approx(x) @ y; } inline const cl_FF operator@ (const float x, const cl_R& y) { return x @ float_approx(y); }
and the same for double. And possibly for cl_F due to efficiency concerns.
The above line of reasoning is entirely wrong. In CLN's type scheme, the return value of operator@ (const cl_F&, float) must be cl_F and not cl_FF. This is because the cl_F argument could actually have been a cl_SF. Then, a cl_SF is returned, which is derived from cl_F, but *not* from cl_FF.
In any case, that operator@ can hardly be said to be an operation in cl_R any more, because it always reduces its arguments precision-wise and does so even by declaration!
Even though that wasn't meant as a mathematically rigorous statement in the first place and even though it might not be technically wrong, it is pointless.
This is why I am reluctant about such operators. If a user wants his nice 1000 digit precision computation to decay he should be forced to state so explicitly.
Still a valid objection. But probably a moot one. No, I haven't been abusing drugs yesterday. Maybe I should have. -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/>
On Fri, 19 Nov 2004, Isidro [iso-8859-15] Cachadiña Gutiérrez wrote:
I don't know if I'm wrong, but why are not defined elsewhere
cln::operator-(const float , const cln::cl_R&)
and some with double, etc. to compile this silly program.
#include <cln/real.h> int main(int argc, char **argv) { cln::cl_F a,b; a=1; b=1.0-a; }
I've committed attached patch into CVS. Please test. Regards -richy. -- Richard B. Kreckel <http://www.ginac.de/~kreckel/>
participants (2)
-
Isidro Cachadiña Gutiérrez
-
Richard B. Kreckel