View Javadoc

1   /*
2    * To change this template, choose Tools | Templates
3    * and open the template in the editor.
4    */
5   package net.sf.zel.nr;
6   
7   import java.math.BigDecimal;
8   import java.math.BigInteger;
9   import javax.annotation.concurrent.Immutable;
10  import net.sf.zel.nr.ExtendedNumber.Type;
11  
12  /**
13   *
14   * @author zoly
15   */
16  @Immutable
17  public final class OperableGNUBigInteger extends OperableGNUNumber
18  {
19      private static final long serialVersionUID = -8692670876118317710L;
20      /**
21       * The pointer is a 64 bit pointer to support 64 bit jvms
22       */
23      private transient long pointer;
24  
25      public static final OperableGNUBigInteger ZERO = new OperableGNUBigInteger("0");
26      public static final OperableGNUBigInteger ONE = new OperableGNUBigInteger("1");
27  
28      public OperableGNUBigInteger(final String number)
29      {
30          pointer = allocateGMP(number);
31      }
32  
33      public OperableGNUBigInteger(final byte[] bytes)
34      {
35          pointer = allocateGMP(toString(bytes, 10));
36      }
37  
38      private OperableGNUBigInteger(final long pointer)
39      {
40          this.pointer = pointer;
41      }
42  
43      @Override
44      protected void finalize() throws Throwable
45      {
46          try
47          {
48              super.finalize();
49          }
50          finally
51          {
52          freeGMP(pointer);
53          }
54      }
55  
56      private static native long allocateGMP(String number);
57  
58      private static native void freeGMP(long pointer);
59  
60      @Override
61      public OperableNumber zero()
62      {
63          return ZERO;
64      }
65  
66      private static native byte[] toByteArray(String number)
67              throws IllegalArgumentException;
68  
69      private static native String toString(byte number[], int base);
70  
71      private static native String toString(long pointer, int base);
72  
73      /**
74       * @experimental     
75       */
76      private static native byte[] add(byte a[], byte b[]);
77  
78      private static native long add(long a, long b);
79  
80      private static native long substract(long a, long b);
81  
82      private static native long multiply(long a, long b);
83  
84      private static native long divide(long a, long b);
85  
86      private static native long mod(long a, long b);
87  
88      @Override
89      public OperableNumber add(OperableNumber addend)
90      {
91          return new OperableGNUBigInteger(add(this.pointer, addend.gnuBigIntegerValue().pointer));
92      }
93  
94      @Override
95      public OperableNumber subtract(OperableNumber subtrahend)
96      {
97          return new OperableGNUBigInteger(substract(this.pointer, subtrahend.gnuBigIntegerValue().pointer));
98      }
99  
100     @Override
101     public OperableNumber multiply(OperableNumber multiplier)
102     {
103         return new OperableGNUBigInteger(multiply(this.pointer, multiplier.gnuBigIntegerValue().pointer));
104     }
105 
106     @Override
107     public OperableNumber divide(OperableNumber divisor)
108     {
109         return new OperableGNUBigInteger(divide(this.pointer, divisor.gnuBigIntegerValue().pointer));
110     }
111 
112     @Override
113     public OperableNumber mod(OperableNumber divisor)
114     {
115         return new OperableGNUBigInteger(mod(this.pointer, divisor.gnuBigIntegerValue().pointer));
116     }
117 
118     @Override
119     public Type getType()
120     {
121         return OperableNumber.Type.INTEGER;
122     }
123 
124     @Override
125     public BigDecimal bigDecimalValue()
126     {
127         throw new UnsupportedOperationException("Not supported yet.");
128     }
129 
130     @Override
131     public BigInteger bigIntegerValue()
132     {
133         throw new UnsupportedOperationException("Not supported yet.");
134     }
135 
136     @Override
137     public OperableGNUBigInteger gnuBigIntegerValue()
138     {
139         return this;
140     }
141 
142     @Override
143     public int intValue()
144     {
145         return Integer.parseInt(toString());
146     }
147 
148     @Override
149     public long longValue()
150     {
151         return Long.parseLong(toString());
152     }
153 
154     @Override
155     public float floatValue()
156     {
157         return Float.parseFloat(toString());
158     }
159 
160     @Override
161     public double doubleValue()
162     {
163         return Double.parseDouble(toString());
164     }
165 
166     @Override
167     public String toString()
168     {
169         return toString(this.pointer, 10);
170     }
171 
172     /**
173      * TODO: current simplistic implementation. need native implementation
174      * and cast the parameter to OperableGNUBIGInteger
175      * @param o
176      * @return
177      */
178 
179     @Override
180     public int compareTo(final Object o)
181     {
182         double other = ((OperableNumber) o).doubleValue();
183         double thisVal = doubleValue();
184         if ( thisVal > other)
185         {
186             return 1;
187         } else if (thisVal == other)
188         {
189             return 0;
190         } else
191         {
192             return -1;
193         }
194     }
195 
196     @Override
197     public OperableGNUBigFloat gnuBigFloatValue()
198     {
199         return new OperableGNUBigFloat(toString());
200     }
201 
202     @Override
203     public int getPrecision()
204     {
205         return 0;
206     }
207 
208     @Override
209     public OperableNumber create(String val)
210     {
211         if ("0".equals(val))
212             return ZERO;
213         else
214             return new OperableGNUBigInteger(val);
215     }
216 
217     @Override
218     public ExtendedNumber one()
219     {
220         return ONE;
221     }
222 
223     @Override
224     public OperableNumber convert(ExtendedNumber val)
225     {
226        return new OperableGNUBigInteger(val.toString());
227     }
228 
229 }