1
2
3
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
15
16 @Immutable
17 public final class OperableGNUBigInteger extends OperableGNUNumber
18 {
19 private static final long serialVersionUID = -8692670876118317710L;
20
21
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
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
174
175
176
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 }