root/trunk/gmp/gmpp.d

Revision 280, 4.9 kB (checked in by mp4, 4 years ago)

object oriented interface to floating point numbers

Line 
1 module gmpp;
2 private import gmp;
3 private import std.string;
4 private import std.stdio;
5 /*object oriented interface to gmp*/
6 const BITS_PER_DIGIT = 3.32192809488736234787;
7 uint precision =  - 1;
8 class mpf
9 {
10   mpf_t v;
11   this()
12   {
13     initialise();
14   }
15   void initialise()
16   {
17     if (precision ==  - 1)
18       mpf_init(&v);
19     else
20       mpf_init2(&v, precision);
21   }
22   ~this()
23   {
24     mpf_clear(&v);
25   }
26   this(uint val)
27   {
28     initialise();
29     mpf_set_ui(&v, val);
30   }
31   this(int val)
32   {
33     initialise();
34     mpf_set_si(&v, val);
35   }
36   this(double val)
37   {
38     initialise();
39     mpf_set_d(&v, val);
40   }
41  
42  
43   template anop(alias f) 
44   {
45     mpf anop()
46     {
47      mpf n = new mpf();
48      f (&n.v, &v);
49      return n;
50     }
51   }
52  
53   mpf opNeg()
54   {
55     mpf n = new mpf();
56     mpf_neg (&n.v, &v);
57     return n;
58   }
59  
60   mpf anopmpf(alias f)(mpf b)
61   {
62     mpf n = new mpf();
63     f (&n.v, &v, &b.v);
64     return n;
65   }
66   mpf anopui(alias f)(uint val)
67   {
68     mpf n = new mpf();
69     f (&n.v, &v, val);
70     return n;
71   }
72   alias anopmpf!(mpf_add) opAdd;
73   alias anopui!(mpf_add_ui) opAdd;
74   alias anopmpf!(mpf_sub) opSub;
75   alias anopui!(mpf_sub_ui) opSub;
76   alias anopmpf!(mpf_mul) opMul;
77   alias anopmpf!(mpf_div) opDiv;
78   alias anopui!(mpf_div_ui) opDiv;
79   alias anopui!(mpf_mul_2exp) mul_2exp;
80   alias anopui!(mpf_div_2exp) div_2exp;
81  
82   alias anop!(mpf_floor) floor;
83   alias anop!(mpf_ceil) ceil;
84   alias anop!(mpf_trunc) trunc;
85   alias anop!(mpf_abs) abs;
86   alias anop!(mpf_sqrt) sqrt;
87  
88   mpf opSub_r(uint val)
89   {
90     mpf n = new mpf();
91     mpf_ui_sub (&n.v, val, &v);
92     return n;
93   }
94  
95   mpf opMul(uint val)
96   {
97     mpf n = new mpf();
98     mpf_mul_ui (&n.v, &v, val);
99     return n;
100   }
101   mpf opMul(int val)
102   {
103   //    writefln("here");
104     mpf n = new mpf();
105     if (val >= 0)
106       mpf_mul_ui (&n.v, &v, val);
107     else
108     {
109       mpf_mul_ui (&n.v, &v, - 1 * val);
110       return n.opNeg();
111     }
112     return n;
113   }
114  
115   mpf opDiv_r(uint val)
116   {
117     mpf n = new mpf();
118     mpf_ui_div (&n.v, val, &v);
119     return n;
120   }
121  
122   char[] toString()
123   {
124     mp_exp_t expptr;
125     uint prec = mpf_get_prec(&v);
126     char[] curres = new char[cast(uint)(cast(float)prec / BITS_PER_DIGIT + 2.)];
127     mpf_get_str (curres.ptr, &expptr, 10, 0, &v);
128    
129     char[] exp = std.string.toString(expptr - 1);
130     if (exp[0] == '-')
131     {
132       if (curres[0] != '-')
133         return curres[0]~"."~std.string.toString(curres[1..$].ptr)~"e"~exp;
134       else
135         return curres[0..2]~"."~std.string.toString(curres[2..$].ptr)~"e"~exp~"e";
136     }
137     else
138     {
139       if (curres[0] != '-')
140         return curres[0]~"."~std.string.toString(curres[1..$].ptr)~"e+"~exp;
141       else
142         return curres[0..2]~"."~std.string.toString(curres[2..$].ptr)~"e+"~exp;
143     }
144   }
145  
146  
147   uint precisionbits()
148   {
149     return mpf_get_prec(&v);
150   }
151   void precisionbits(uint prec)
152   {
153     mpf_set_prec(&v, prec);
154   }
155   uint precisiondigits()
156   {
157     return cast(uint)(cast(float)mpf_get_prec(&v) / BITS_PER_DIGIT + 0.9999999);
158   }
159   void precisiondigits(uint digits)
160   {
161     mpf_set_prec(&v, cast(uint)(cast(float)digits * BITS_PER_DIGIT));
162   }
163 // Function: void mpf_set_z (mpf_t rop, mpz_t op)
164 // Function: void mpf_set_q (mpf_t rop, mpq_t op)       
165  
166 } 
167
168
169 mpf sqrt_ui(uint a)
170 {
171   mpf n = new mpf();
172   mpf_sqrt_ui (&n.v, a);
173   return n;
174 } 
175
176 mpf mpf_call(alias f)(mpf a)
177 {
178   mpf n = new mpf();
179   f (&n.v, &a.v);
180   return n;
181 } 
182 alias mpf_call!(mpf_sqrt) sqrt;
183 alias mpf_call!(mpf_abs) abs;
184 alias mpf_call!(mpf_ceil) ceil;
185 alias mpf_call!(mpf_floor) floor;
186 alias mpf_call!(mpf_trunc) trunc;
187
188
189
190 version(test)
191 void main()
192 {
193   writefln("unittest");
194   mpf a = new mpf(2);
195   writefln("a:", a);
196   a = a * 2;
197   writefln("2*a:", a);
198   a = a / 2;
199   writefln("2*a/2:", a);
200   a = a + 3;
201   writefln("a+3:", a);
202   a = a * new mpf(4.1);
203   writefln("a*4.1:", a);
204   a = a - 8;
205   writefln("a-8:", a);
206   a = a * - 1;
207   writefln("a*-1:", a);
208   a = - a;
209   writefln("-a:", a);
210   a = 2 / a;
211   writefln("2/a:", a);
212   a = new mpf(2);
213   writefln("sqrt(a):", sqrt(a));
214   writefln("abs(-a)):", abs( - a));
215   writefln("floor sqrt(a):", floor(sqrt(a)));
216   writefln("ceil sqrt(a):", ceil(sqrt(a)));
217   writefln("trunc sqrt(a):", trunc(sqrt(a)));
218   precision = 400; // for new numbers and for temporal results
219   writefln("precision=400 trunc sqrt(a):", trunc(sqrt(a)));
220   a.precisionbits = 100;
221   a = a + 1 / 3;
222   writefln("a:", a," ", a.precisionbits," ", a.precisiondigits);
223   a.precisionbits = 250;
224   writefln("a:", a," ", a.precisionbits," ", a.precisiondigits);
225   a.precisionbits = 300;
226   writefln("a:", a," ", a.precisionbits," ", a.precisiondigits);
227   a = new mpf(10000);
228   writefln("a:", a," ", a.precisionbits," ", a.precisiondigits);
229   writefln("floor.trunc.ceil.abs.sqrt a:", a.floor.trunc.ceil.abs.sqrt);
230 } 
Note: See TracBrowser for help on using the browser.