// recip().
// General includes.
#include "cl_sysdep.h"
// Specification.
#include "cln/complex.h"
// Implementation.
#include "cl_C.h"
#include "cln/real.h"
#include "cl_R.h"
#include "cln/rational.h"
#include "cl_RA.h"
#include "cl_F.h"
#include "cl_SF.h"
#include "cl_FF.h"
#include "cl_DF.h"
#include "cl_LF.h"
namespace cln {
ALL_cl_LF_OPERATIONS_SAME_PRECISION()
// for GEN_F_OP2:
#define NOMAP2(F,EXPR) \
cl_C_##F _tmp = EXPR; \
return complex_C(_tmp.realpart,_tmp.imagpart);
#define MAP2(F,FN,EXPR) \
cl_C_##F _tmp = EXPR; \
return complex_C(FN(_tmp.realpart),FN(_tmp.imagpart))
const cl_N recip (const cl_N& x)
{
// Methode:
// Falls x reell, klar.
// Falls x=a+bi:
// Falls a=0: 0+(-1/b)i.
// Falls a und b beide rational sind:
// c:=a*a+b*b, c:=1/c, liefere a*c+(-b*c)i.
// Falls a oder b Floats sind:
// Falls einer von beiden rational ist, runde ihn zum selben Float-Typ
// wie der andere und führe das UP durch.
// Falls beide Floats sind, erweitere auf den genaueren, führe das UP
// durch und runde wieder auf den ungenaueren.
// Das Ergebnis ist eine komplexe Zahl, da beide Komponenten Floats sind.
// UP: [a,b Floats vom selben Typ]
// a=0.0 -> liefere die Komponenten a=0.0 und -1/b.
// b=0.0 -> liefere die Komponenten 1/a und b=0.0.
// e:=max(exponent(a),exponent(b)).
// a':=a/2^e bzw. 0.0 bei Underflowmöglichkeit (beim Skalieren a':=a/2^e
// oder beim Quadrieren a'*a': 2*(e-exponent(a))>exp_mid-exp_low-1
// d.h. exponent(b)-exponent(a)>floor((exp_mid-exp_low-1)/2) ).
// b':=b/2^e bzw. 0.0 bei Underflowmöglichkeit (beim Skalieren b':=b/2^e
// oder beim Quadrieren b'*b': 2*(e-exponent(b))>exp_mid-exp_low-1
// d.h. exponent(a)-exponent(b)>floor((exp_mid-exp_low-1)/2) ).
// c':=a'*a'+b'*b',
// liefere die beiden Komponenten 2^(-e)*a'/c' und -2^(-e)*b'/c'.
if (realp(x)) {
DeclareType(cl_R,x);
return recip(x);
} else
{
DeclareType(cl_C,x);
var const cl_R& a = realpart(x);
var const cl_R& b = imagpart(x);
// x = a+bi
if (rationalp(a)) {
DeclareType(cl_RA,a);
if (eq(a,0))
// (complex 0 (- (/ b)))
return complex_C(0,-recip(b));
if (rationalp(b)) {
DeclareType(cl_RA,b);
// a,b beide rational
var cl_RA c = recip(square(a)+square(b));
return complex_C(a*c,-b*c);
} else {
DeclareType(cl_F,b);
// a rational, b Float
floatcase(b
, return complex_C(cl_C_recip(cl_RA_to_SF(a),b));
, return complex_C(cl_C_recip(cl_RA_to_FF(a),b));
, return complex_C(cl_C_recip(cl_RA_to_DF(a),b));
, return complex_C(cl_C_recip(cl_RA_to_LF(a,TheLfloat(b)->len),b));
);
}
} else {
DeclareType(cl_F,a);
if (rationalp(b)) {
DeclareType(cl_RA,b);
// a Float, b rational
floatcase(a
, return complex_C(cl_C_recip(a,cl_RA_to_SF(b)));
, return complex_C(cl_C_recip(a,cl_RA_to_FF(b)));
, return complex_C(cl_C_recip(a,cl_RA_to_DF(b)));
, return complex_C(cl_C_recip(a,cl_RA_to_LF(b,TheLfloat(a)->len)));
);
} else {
DeclareType(cl_F,b);
// a,b Floats
#ifndef CL_LF_PEDANTIC
GEN_F_OP2(a,b,cl_C_recip,2,1,); // uses NOMAP2, MAP2.
#else
GEN_F_OP2(a,b,cl_C_recip,2,0,); // uses NOMAP2, MAP2.
#endif
}
}
}
}
} // namespace cln
syntax highlighted by Code2HTML, v. 0.9.1