PageRenderTime 43ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/cln-1.3.2/src/rational/elem/cl_RA_minus.cc

#
C++ | 114 lines | 59 code | 8 blank | 47 comment | 10 complexity | 5e4092b849d719fe8b6d0f83a2fbf4c7 MD5 | raw file
Possible License(s): GPL-2.0
  1. // binary operator -
  2. // General includes.
  3. #include "base/cl_sysdep.h"
  4. // Specification.
  5. #include "cln/rational.h"
  6. // Implementation.
  7. #include "rational/cl_RA.h"
  8. #include "cln/integer.h"
  9. #include "integer/cl_I.h"
  10. namespace cln {
  11. const cl_RA operator- (const cl_RA& r, const cl_RA& s)
  12. {
  13. #if 0
  14. // Methode:
  15. // (+ r (- s))
  16. return r + (- s);
  17. #else
  18. // Methode (vgl. [Buchberger, Collins, Loos: Computer Algebra, S.200-201])
  19. // r,s beide Integers -> klar.
  20. // r=a/b, s=c -> Ergebnis (a-b*c)/b
  21. // (mit b>1 und ggT(a-b*c,b) = ggT(a,b) = 1)
  22. // Bei c=0 direkt r als Ergebnis.
  23. // r=a, s=c/d -> Ergebnis (a*d-c)/d
  24. // (mit d>1 und ggT(a*d-c,d) = ggT(-c,d) = ggT(c,d) = 1)
  25. // Bei a=0 direkt -s = (-c)/d als Ergebnis.
  26. // r=a/b, s=c/d:
  27. // g:=ggT(b,d)>0.
  28. // Falls g=1:
  29. // Ergebnis (a*d-b*c)/(b*d),
  30. // (mit b*d>1 wegen b>1, d>1, und
  31. // ggT(a*d-b*c,b*d) = 1
  32. // wegen ggT(a*d-b*c,b) = ggT(a*d,b) = 1 (wegen ggT(a,b)=1 und ggT(d,b)=1)
  33. // und ggT(a*d-b*c,d) = ggT(b*c,d) = 1 (wegen ggT(b,d)=1 und ggT(c,d)=1)
  34. // )
  35. // Sonst b' := b/g, d' := d/g. e := a*d'-b'*c, f:= b'*d = b*d'.
  36. // Es ist g = ggT(g*b',g*d') = g*ggT(b',d'), also ggT(b',d')=1.
  37. // Es ist r-s = (a*d-b*c)/(b*d) = (nach K??rzen mit g) e/f.
  38. // Au?&#x;erdem:
  39. // ggT(a,b') teilt ggT(a,b)=1, also ggT(a,b')=1. Mit ggT(d',b')=1 folgt
  40. // 1 = ggT(a*d',b') = ggT(a*d'-b'*c,b') = ggT(e,b').
  41. // ggT(c,d') teilt ggT(c,d)=1, also ggT(c,d')=1. Mit ggT(b',d')=1 folgt
  42. // 1 = ggT(b'*c,d') = ggT(a*d'-b'*c,d') = ggT(e,d').
  43. // Daher ist ggT(e,f) = ggT(e,b'*d'*g) = ggT(e,g).
  44. // Errechne daher h=ggT(e,g).
  45. // Bei h=1 ist e/f das Ergebnis (mit f>1, da d>1, und ggT(e,f)=1),
  46. // sonst ist (e/h)/(f/h) das Ergebnis.
  47. if (integerp(s)) {
  48. // s ist Integer
  49. DeclareType(cl_I,s);
  50. if (eq(s,0)) { return r; } // s=0 -> r als Ergebnis
  51. if (integerp(r)) {
  52. // beides Integers
  53. DeclareType(cl_I,r);
  54. return r-s;
  55. } else {
  56. DeclareType(cl_RT,r);
  57. var const cl_I& a = numerator(r);
  58. var const cl_I& b = denominator(r);
  59. var const cl_I& c = s;
  60. // r = a/b, s = c.
  61. return I_I_to_RT(a-b*c,b);
  62. }
  63. } else {
  64. // s ist Ratio
  65. DeclareType(cl_RT,s);
  66. if (integerp(r)) {
  67. // r ist Integer
  68. DeclareType(cl_I,r);
  69. if (eq(r,0)) {
  70. // r=0 -> -s als Ergebnis
  71. var const cl_I& c = numerator(s);
  72. var const cl_I& d = denominator(s);
  73. return I_I_to_RT(-c,d);
  74. }
  75. var const cl_I& a = r;
  76. var const cl_I& c = numerator(s);
  77. var const cl_I& d = denominator(s);
  78. // r = a, s = c/d.
  79. return I_I_to_RT(a*d-c,d);
  80. } else {
  81. // r,s beide Ratios
  82. DeclareType(cl_RT,r);
  83. var const cl_I& a = numerator(r);
  84. var const cl_I& b = denominator(r);
  85. var const cl_I& c = numerator(s);
  86. var const cl_I& d = denominator(s);
  87. var cl_I g = gcd(b,d); // g = ggT(b,d) >0 bilden
  88. if (eq(g,1))
  89. // g=1 -> Ergebnis (a*d-b*c)/(b*d)
  90. return I_I_to_RT(a*d-b*c,b*d);
  91. // g>1
  92. var cl_I bp = exquopos(b,g); // b' := b/g (b,g>0)
  93. var cl_I dp = exquopos(d,g); // d' := d/g (d,g>0)
  94. var cl_I e = a*dp-bp*c; // e := a*d'-b'*c
  95. var cl_I f = bp*d; // f := b'*d
  96. var cl_I h = gcd(e,g); // h := ggT(e,g)
  97. if (eq(h,1))
  98. // h=1
  99. return I_I_to_RT(e,f);
  100. // h>1
  101. return I_I_to_RA(exquo(e,h),exquopos(f,h)); // (e/h)/(f/h) als Ergebnis
  102. }
  103. }
  104. #endif
  105. }
  106. } // namespace cln