KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > math > DFloNum


1 // Copyright (c) 1997 Per M.A. Bothner.
2
// This is free software; for terms and warranty disclaimer see ./COPYING.
3

4 package gnu.math;
5 import java.io.*;
6
7 public class DFloNum extends RealNum implements Externalizable
8 {
9   double value;
10
11   public DFloNum ()
12   {
13   }
14
15   public DFloNum (double value)
16   {
17     this.value = value;
18   }
19
20   public DFloNum (String JavaDoc s) throws NumberFormatException JavaDoc
21   {
22     Double JavaDoc d = Double.valueOf (s); // wasteful ...
23
value = d.doubleValue ();
24
25     // We want "-0.0" to convert to -0.0, but the spec as of 1.1
26
// requires Double.valueOf to convert it to 0.0, because the
27
// method is defined to be equivalent to first computing the exact
28
// rational value and then converting to floating-point, and the
29
// exact rational value represented by either string "0.0" or
30
// "-0.0" is 0.
31

32     // This is apparently a bug in the spec, which I've reported
33
// to sun. As of 1.1, the sun implementation returns -0.0,
34
// but the linux port returns 0.0.
35

36     // To be safe, we check for this case.
37
if (value == 0.0 && s.charAt (0) == '-')
38       value = -0.0;
39   }
40
41   public static DFloNum make (double value)
42   {
43     return new DFloNum (value);
44   }
45
46   public final double doubleValue ()
47   {
48     return value;
49   }
50
51   public long longValue ()
52   {
53     return (long) value;
54   }
55
56   public int hashCode ()
57   {
58     return (int)value;
59   }
60
61   public boolean equals (Object JavaDoc obj)
62   {
63     // take from java.lang.Double.equals:
64
return (obj != null)
65       && (obj instanceof DFloNum)
66       && (Double.doubleToLongBits(((DFloNum)obj).value)
67       == Double.doubleToLongBits(value));
68   }
69
70   public Numeric add (Object JavaDoc y, int k)
71   {
72     if (y instanceof RealNum)
73       return new DFloNum (value + k * ((RealNum)y).doubleValue ());
74     if (!(y instanceof Numeric))
75       throw new IllegalArgumentException JavaDoc ();
76     return ((Numeric)y).addReversed(this, k);
77   }
78
79   public Numeric addReversed (Numeric x, int k)
80   {
81     if (x instanceof RealNum)
82       return new DFloNum (((RealNum)x).doubleValue () + k * value);
83     throw new IllegalArgumentException JavaDoc ();
84   }
85
86   public Numeric mul (Object JavaDoc y)
87   {
88     if (y instanceof RealNum)
89       return new DFloNum (value * ((RealNum)y).doubleValue ());
90     if (!(y instanceof Numeric))
91       throw new IllegalArgumentException JavaDoc ();
92     return ((Numeric)y).mulReversed(this);
93   }
94
95   public Numeric mulReversed (Numeric x)
96   {
97     if (x instanceof RealNum)
98       return new DFloNum (((RealNum)x).doubleValue () * value);
99     throw new IllegalArgumentException JavaDoc ();
100   }
101
102   private static final DFloNum one = new DFloNum(1.0);
103   public static final DFloNum one() { return one; }
104
105   public Numeric div (Object JavaDoc y)
106   {
107     if (y instanceof RealNum)
108       return new DFloNum (value / ((RealNum)y).doubleValue ());
109     if (!(y instanceof Numeric))
110       throw new IllegalArgumentException JavaDoc ();
111     return ((Numeric)y).divReversed(this);
112   }
113
114   public Numeric divReversed (Numeric x)
115   {
116     if (x instanceof RealNum)
117       return new DFloNum (((RealNum)x).doubleValue () / value);
118     throw new IllegalArgumentException JavaDoc ();
119   }
120
121   public Numeric power (IntNum y)
122   {
123     return new DFloNum (Math.pow (doubleValue(), y.doubleValue()));
124   }
125
126   public boolean isNegative ()
127   {
128     return value < 0;
129   }
130
131   public Numeric neg ()
132   {
133     return new DFloNum (-value);
134   }
135
136   public int sign ()
137   {
138     return value > 0.0 ? 1 : value < 0.0 ? -1 : value == 0.0 ? 0: -2;
139   }
140
141   public static int compare (double x, double y)
142   {
143     return x > y ? 1 : x < y ? -1 : x == y ? 0 : -2;
144   }
145
146   /** Compare (x_num/x_den) with toExact(y). */
147   public static int compare(IntNum x_num, IntNum x_den, double y)
148   {
149     if (Double.isNaN (y))
150       return -2;
151     if (Double.isInfinite (y))
152       {
153     int result = y >= 0.0 ? -1 : 1;
154     if (! x_den.isZero())
155       return result; // x is finite
156
if (x_num.isZero())
157       return -2; // indeterminate x
158
result >>= 1;
159     return x_num.isNegative() ? result : ~result;
160       }
161     else
162       {
163     long bits = Double.doubleToLongBits (y);
164     boolean neg = bits < 0;
165     int exp = (int) (bits >> 52) & 0x7FF;
166     bits &= 0xfffffffffffffL;
167     if (exp == 0)
168       bits <<= 1;
169     else
170       bits |= 0x10000000000000L;
171     IntNum y_num = IntNum.make (neg ? -bits : bits);
172     if (exp >= 1075)
173       y_num = IntNum.shift (y_num, exp - 1075);
174     else
175       x_num = IntNum.shift (x_num, 1075 - exp);
176     return IntNum.compare (x_num, IntNum.times (y_num, x_den));
177       }
178   }
179
180   public int compare (Object JavaDoc obj)
181   {
182     if (obj instanceof RatNum)
183       {
184     RatNum y_rat = (RatNum) obj;
185     int i = compare(y_rat.numerator(), y_rat.denominator(), value);
186     return i < -1 ? i : -i;
187       }
188     return compare (value, ((RealNum)obj).doubleValue ());
189   }
190
191   public int compareReversed (Numeric x)
192   {
193     if (x instanceof RatNum)
194       {
195     RatNum x_rat = (RatNum) x;
196     return compare(x_rat.numerator(), x_rat.denominator(), value);
197       }
198     return compare (((RealNum)x).doubleValue (), value);
199   }
200
201   public boolean isExact ()
202   {
203     return false;
204   }
205
206   public boolean isZero ()
207   {
208     return value == 0.0;
209   }
210
211   /** Converts to the closest exact rational value. */
212   public static RatNum toExact (double value)
213   {
214     if (Double.isInfinite (value))
215       return RatNum.infinity(value >= 0.0 ? 1 : -1);
216     if (Double.isNaN (value))
217       throw new ArithmeticException JavaDoc ("cannot convert NaN to exact rational");
218     long bits = Double.doubleToLongBits (value);
219     boolean neg = bits < 0;
220     int exp = (int) (bits >> 52) & 0x7FF;
221     bits &= 0xfffffffffffffL;
222     if (exp == 0)
223       bits <<= 1;
224     else
225       bits |= 0x10000000000000L;
226     IntNum mant = IntNum.make (neg ? -bits : bits);
227     if (exp >= 1075)
228       return IntNum.shift (mant, exp - 1075);
229     else
230       return RatNum.make (mant, IntNum.shift (IntNum.one(), 1075 - exp));
231   }
232
233    public String JavaDoc toString ()
234    {
235     return (value == 1.0/0.0 ? "#i1/0"
236         : value == -1.0/0.0 ? "#i-1/0"
237         : Double.isNaN (value) ? "#i0/0"
238         : Double.toString (value));
239    }
240
241    public String JavaDoc toString (int radix)
242    {
243     if (radix == 10)
244       return toString ();
245     return "#d" + toString ();
246    }
247
248   /**
249    * @serialData Writes the number as a double (using writeDouble).
250    */

251   public void writeExternal(ObjectOutput out) throws IOException
252   {
253     out.writeDouble(value);
254   }
255
256   public void readExternal(ObjectInput in)
257     throws IOException, ClassNotFoundException JavaDoc
258   {
259     value = in.readDouble();
260   }
261
262   /*
263   static final int mine_e = -1024;
264   static final long bp_1 = 1L << 52;
265
266   static ?? flonum_digits (foubel v, long f, int e)
267   {
268     boolean round_p = (f & 1) == 0;
269     if (e >= 0)
270       {
271     IntNum be = 1L << e; // ???
272     if (f != bp_1)
273       return scale (f * be * 2 (?), 2, be, be, 0, round_p, round_p, v);
274     else
275       return scale (f * be * 4 (?), 4, 2 * be, b2, 0, round_p, round_p, v);
276       }
277     else
278       {
279     if (e == min_e || f != bp_1)
280       return scale (f * 2 (?), 2 ** (1 - 3), 1, 1, 0, round_p, round_p, v);
281     else
282       return scale (f * 4 (?), 2 ** (2 - e), 2, 1, 0, round_p, round_p, v);
283       }
284   }
285
286   static ?? scale (IntNum r, IntNum s, IntNum m_plus, IntNum m_minus,
287            int k, boolean low_ok?, boolean high_ok, double v)
288   {
289     int est = (int) Math.ceil(log10(v) - 1e-10);
290     if (est >= 0)
291       return fixup(r, s * expt10(est), m_plus, m_minus, est, low_ok, high_ok);
292     else
293       {
294     IntNum scale = expt10(-ext);
295     return fixup(r * scale, s, scale * m_plus, scale * m_minus,
296              est, low_ok, high_ok);
297       }
298   }
299
300   static ?? fixup (IntNum r, IntNum s, IntNum m_plus, IntNum m_minus,
301            int k, boolean low_ok, boolean high_ok)
302   {
303     ...;
304   }
305
306   static ?? generate (IntNum r, IntNum s, IntNum m_plus, IntNum m_minus,
307               boolean low_ok, boolean high_ok)
308   {
309     IntNum d = new IntNum(), r = new IntNum();
310     IntNum.divide (r, s, d, r, mode?);
311     d = d.canonicalize();
312     r = r.canonicalize();
313     boolean tc1 = ?;
314     boolean tc2 = ?;
315   }
316
317   static IntNum expt10 = null;
318
319   static IntNum expt10 (int k)
320   {
321     if (expt10 == null)
322       {
323     expt10 = new IntNum[326];
324     int i = 0;
325     IntNum v = IntNum.one();
326     for (; ; i++)
327       {
328         expt10[i] = v;
329         if (i == 325)
330           break;
331         v = IntNum.times(v, 10);
332       }
333       }
334     return expt10[k];
335   }
336
337   static double InvLog10 = 1.0 / Math.log(10);
338   
339   static double log10 (double x) { return Math.log(x) * InvLog10; }
340   */

341 }
342
Popular Tags