1 |
// ********************************************************************** |
2 |
// |
3 |
// <copyright> |
4 |
// |
5 |
// BBN Technologies |
6 |
// 10 Moulton Street |
7 |
// Cambridge, MA 02138 |
8 |
// (617) 873-8000 |
9 |
// |
10 |
// Copyright (C) BBNT Solutions LLC. All rights reserved. |
11 |
// |
12 |
// </copyright> |
13 |
// ********************************************************************** |
14 |
// |
15 |
// $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/MoreMath.java,v $ |
16 |
// $RCSfile: MoreMath.java,v $ |
17 |
// $Revision: 1.3.2.1 $ |
18 |
// $Date: 2004/10/14 18:26:37 $ |
19 |
// $Author: dietrick $ |
20 |
// |
21 |
// ********************************************************************** |
22 |
|
23 |
package dk.thoerup.traininfoservice.geo; |
24 |
|
25 |
/** |
26 |
* MoreMath provides functions that are not part of the standard Math |
27 |
* class. |
28 |
* <p> |
29 |
* |
30 |
* <pre> |
31 |
* |
32 |
* Functions: |
33 |
* asinh(float x) - hyperbolic arcsine |
34 |
* sinh(float x) - hyperbolic sine |
35 |
* |
36 |
* Need to Implement: |
37 |
* Function Definition |
38 |
* Hyperbolic cosine (eˆx+eˆ-x)/2 |
39 |
* Hyperbolic tangent (eˆx-eˆ-x)/(eˆx+eˆ-x) |
40 |
* Hyperbolic arc cosine 2 log (sqrt((x+1)/2) + sqrt((x-1)/2)) |
41 |
* Hyperbolic arc tangent (log (1+x) - log (1-x))/2 |
42 |
* |
43 |
* </pre> |
44 |
*/ |
45 |
public class MoreMath { |
46 |
|
47 |
/** |
48 |
* 2*Math.PI |
49 |
*/ |
50 |
final public static transient float TWO_PI = (float) Math.PI * 2.0f; |
51 |
|
52 |
/** |
53 |
* 2*Math.PI |
54 |
*/ |
55 |
final public static transient double TWO_PI_D = Math.PI * 2.0d; |
56 |
|
57 |
/** |
58 |
* Math.PI/2 |
59 |
*/ |
60 |
final public static transient float HALF_PI = (float) Math.PI / 2.0f; |
61 |
|
62 |
/** |
63 |
* Math.PI/2 |
64 |
*/ |
65 |
final public static transient double HALF_PI_D = Math.PI / 2.0d; |
66 |
|
67 |
// cannot construct |
68 |
private MoreMath() {} |
69 |
|
70 |
/** |
71 |
* Checks if a ~= b. Use this to test equality of floating point |
72 |
* numbers. |
73 |
* <p> |
74 |
* |
75 |
* @param a double |
76 |
* @param b double |
77 |
* @param epsilon the allowable error |
78 |
* @return boolean |
79 |
*/ |
80 |
final public static boolean approximately_equal(double a, double b, |
81 |
double epsilon) { |
82 |
return (Math.abs(a - b) <= epsilon); |
83 |
} |
84 |
|
85 |
/** |
86 |
* Checks if a ~= b. Use this to test equality of floating point |
87 |
* numbers. |
88 |
* <p> |
89 |
* |
90 |
* @param a float |
91 |
* @param b float |
92 |
* @param epsilon the allowable error |
93 |
* @return boolean |
94 |
*/ |
95 |
final public static boolean approximately_equal(float a, float b, |
96 |
float epsilon) { |
97 |
return (Math.abs(a - b) <= epsilon); |
98 |
} |
99 |
|
100 |
/** |
101 |
* Hyperbolic arcsin. |
102 |
* <p> |
103 |
* Hyperbolic arc sine: log (x+sqrt(1+x^2)) |
104 |
* |
105 |
* @param x float |
106 |
* @return float asinh(x) |
107 |
*/ |
108 |
public static final float asinh(float x) { |
109 |
return (float) Math.log(x + Math.sqrt(x * x + 1)); |
110 |
} |
111 |
|
112 |
/** |
113 |
* Hyperbolic arcsin. |
114 |
* <p> |
115 |
* Hyperbolic arc sine: log (x+sqrt(1+x^2)) |
116 |
* |
117 |
* @param x double |
118 |
* @return double asinh(x) |
119 |
*/ |
120 |
public static final double asinh(double x) { |
121 |
return (double) Math.log(x + Math.sqrt(x * x + 1)); |
122 |
} |
123 |
|
124 |
/** |
125 |
* Hyperbolic sin. |
126 |
* <p> |
127 |
* Hyperbolic sine: (e^x-e^-x)/2 |
128 |
* |
129 |
* @param x float |
130 |
* @return float sinh(x) |
131 |
*/ |
132 |
public static final float sinh(float x) { |
133 |
return (float) (Math.pow(Math.E, x) - Math.pow(Math.E, -x)) / 2.0f; |
134 |
} |
135 |
|
136 |
/** |
137 |
* Hyperbolic sin. |
138 |
* <p> |
139 |
* Hyperbolic sine: (e^x-e^-x)/2 |
140 |
* |
141 |
* @param x double |
142 |
* @return double sinh(x) |
143 |
*/ |
144 |
public static final double sinh(double x) { |
145 |
return (double) (Math.pow(Math.E, x) - Math.pow(Math.E, -x)) / 2.0d; |
146 |
} |
147 |
|
148 |
// HACK - are there functions that already exist? |
149 |
/** |
150 |
* Return sign of number. |
151 |
* |
152 |
* @param x short |
153 |
* @return int sign -1, 1 |
154 |
*/ |
155 |
public static final int sign(short x) { |
156 |
return (x < 0) ? -1 : 1; |
157 |
} |
158 |
|
159 |
/** |
160 |
* Return sign of number. |
161 |
* |
162 |
* @param x int |
163 |
* @return int sign -1, 1 |
164 |
*/ |
165 |
public static final int sign(int x) { |
166 |
return (x < 0) ? -1 : 1; |
167 |
} |
168 |
|
169 |
/** |
170 |
* Return sign of number. |
171 |
* |
172 |
* @param x long |
173 |
* @return int sign -1, 1 |
174 |
*/ |
175 |
public static final int sign(long x) { |
176 |
return (x < 0) ? -1 : 1; |
177 |
} |
178 |
|
179 |
/** |
180 |
* Return sign of number. |
181 |
* |
182 |
* @param x float |
183 |
* @return int sign -1, 1 |
184 |
*/ |
185 |
public static final int sign(float x) { |
186 |
return (x < 0f) ? -1 : 1; |
187 |
} |
188 |
|
189 |
/** |
190 |
* Return sign of number. |
191 |
* |
192 |
* @param x double |
193 |
* @return int sign -1, 1 |
194 |
*/ |
195 |
public static final int sign(double x) { |
196 |
return (x < 0d) ? -1 : 1; |
197 |
} |
198 |
|
199 |
/** |
200 |
* Check if number is odd. |
201 |
* |
202 |
* @param x short |
203 |
* @return boolean |
204 |
*/ |
205 |
public static final boolean odd(short x) { |
206 |
return !even(x); |
207 |
} |
208 |
|
209 |
/** |
210 |
* Check if number is odd. |
211 |
* |
212 |
* @param x int |
213 |
* @return boolean |
214 |
*/ |
215 |
public static final boolean odd(int x) { |
216 |
return !even(x); |
217 |
} |
218 |
|
219 |
/** |
220 |
* Check if number is odd. |
221 |
* |
222 |
* @param x long |
223 |
* @return boolean |
224 |
*/ |
225 |
public static final boolean odd(long x) { |
226 |
return !even(x); |
227 |
} |
228 |
|
229 |
/** |
230 |
* Check if number is even. |
231 |
* |
232 |
* @param x short |
233 |
* @return boolean |
234 |
*/ |
235 |
public static final boolean even(short x) { |
236 |
return ((x & 0x1) == 0); |
237 |
} |
238 |
|
239 |
/** |
240 |
* Check if number is even. |
241 |
* |
242 |
* @param x int |
243 |
* @return boolean |
244 |
*/ |
245 |
public static final boolean even(int x) { |
246 |
return ((x & 0x1) == 0); |
247 |
} |
248 |
|
249 |
/** |
250 |
* Check if number is even. |
251 |
* |
252 |
* @param x long |
253 |
* @return boolean |
254 |
*/ |
255 |
public static final boolean even(long x) { |
256 |
return ((x & 0x1) == 0); |
257 |
} |
258 |
|
259 |
/** |
260 |
* Converts a byte in the range of -128 to 127 to an int in the |
261 |
* range 0 - 255. |
262 |
* |
263 |
* @param b (-128 <= b <= 127) |
264 |
* @return int (0 <= b <= 255) |
265 |
*/ |
266 |
public static final int signedToInt(byte b) { |
267 |
return ((int) b & 0xff); |
268 |
} |
269 |
|
270 |
/** |
271 |
* Converts a short in the range of -32768 to 32767 to an int in |
272 |
* the range 0 - 65535. |
273 |
* |
274 |
* @param w (-32768 <= b <= 32767) |
275 |
* @return int (0 <= b <= 65535) |
276 |
*/ |
277 |
public static final int signedToInt(short w) { |
278 |
return ((int) w & 0xffff); |
279 |
} |
280 |
|
281 |
/** |
282 |
* Convert an int in the range of -2147483648 to 2147483647 to a |
283 |
* long in the range 0 to 4294967295. |
284 |
* |
285 |
* @param x (-2147483648 <= x <= 2147483647) |
286 |
* @return long (0 <= x <= 4294967295) |
287 |
*/ |
288 |
public static final long signedToLong(int x) { |
289 |
return ((long) x & 0xFFFFFFFFL); |
290 |
} |
291 |
|
292 |
/** |
293 |
* Converts an int in the range of 0 - 65535 to an int in the |
294 |
* range of 0 - 255. |
295 |
* |
296 |
* @param w int (0 <= w <= 65535) |
297 |
* @return int (0 <= w <= 255) |
298 |
*/ |
299 |
public static final int wordToByte(int w) { |
300 |
return w >> 8; |
301 |
} |
302 |
|
303 |
/** |
304 |
* Build short out of bytes (in big endian order). |
305 |
* |
306 |
* @param bytevec bytes |
307 |
* @param offset byte offset |
308 |
* @return short |
309 |
*/ |
310 |
public static final short BuildShortBE(byte bytevec[], int offset) { |
311 |
return (short) (((int) (bytevec[0 + offset]) << 8) | (signedToInt(bytevec[1 + offset]))); |
312 |
} |
313 |
|
314 |
/** |
315 |
* Build short out of bytes (in little endian order). |
316 |
* |
317 |
* @param bytevec bytes |
318 |
* @param offset byte offset |
319 |
* @return short |
320 |
*/ |
321 |
public static final short BuildShortLE(byte bytevec[], int offset) { |
322 |
return (short) (((int) (bytevec[1 + offset]) << 8) | (signedToInt(bytevec[0 + offset]))); |
323 |
} |
324 |
|
325 |
/** |
326 |
* Build short out of bytes. |
327 |
* |
328 |
* @param bytevec bytes |
329 |
* @param offset byte offset |
330 |
* @param MSBFirst BE or LE? |
331 |
* @return short |
332 |
*/ |
333 |
public static final short BuildShort(byte bytevec[], int offset, |
334 |
boolean MSBFirst) { |
335 |
if (MSBFirst) { |
336 |
return (BuildShortBE(bytevec, offset)); |
337 |
} else { |
338 |
return (BuildShortLE(bytevec, offset)); |
339 |
} |
340 |
} |
341 |
|
342 |
/** |
343 |
* Build short out of bytes (in big endian order). |
344 |
* |
345 |
* @param bytevec bytes |
346 |
* @param MSBFirst BE or LE? |
347 |
* @return short |
348 |
*/ |
349 |
|
350 |
public static final short BuildShortBE(byte bytevec[], boolean MSBFirst) { |
351 |
return BuildShortBE(bytevec, 0); |
352 |
} |
353 |
|
354 |
/** |
355 |
* Build short out of bytes (in little endian order). |
356 |
* |
357 |
* @param bytevec bytes |
358 |
* @param MSBFirst BE or LE? |
359 |
* @return short |
360 |
*/ |
361 |
public static final short BuildShortLE(byte bytevec[], boolean MSBFirst) { |
362 |
return BuildShortLE(bytevec, 0); |
363 |
} |
364 |
|
365 |
/** |
366 |
* Build short out of bytes. |
367 |
* |
368 |
* @param bytevec bytes |
369 |
* @param MSBFirst BE or LE? |
370 |
* @return short |
371 |
*/ |
372 |
public static final short BuildShort(byte bytevec[], boolean MSBFirst) { |
373 |
return BuildShort(bytevec, 0, MSBFirst); |
374 |
} |
375 |
|
376 |
/** |
377 |
* Build int out of bytes (in big endian order). |
378 |
* |
379 |
* @param bytevec bytes |
380 |
* @param offset byte offset |
381 |
* @return int |
382 |
*/ |
383 |
public static final int BuildIntegerBE(byte bytevec[], int offset) { |
384 |
return (((int) (bytevec[0 + offset]) << 24) |
385 |
| (signedToInt(bytevec[1 + offset]) << 16) |
386 |
| (signedToInt(bytevec[2 + offset]) << 8) | (signedToInt(bytevec[3 + offset]))); |
387 |
} |
388 |
|
389 |
/** |
390 |
* Build int out of bytes (in little endian order). |
391 |
* |
392 |
* @param bytevec bytes |
393 |
* @param offset byte offset |
394 |
* @return int |
395 |
*/ |
396 |
public static final int BuildIntegerLE(byte bytevec[], int offset) { |
397 |
return (((int) (bytevec[3 + offset]) << 24) |
398 |
| (signedToInt(bytevec[2 + offset]) << 16) |
399 |
| (signedToInt(bytevec[1 + offset]) << 8) | (signedToInt(bytevec[0 + offset]))); |
400 |
} |
401 |
|
402 |
/** |
403 |
* Build int out of bytes. |
404 |
* |
405 |
* @param bytevec bytes |
406 |
* @param offset byte offset |
407 |
* @param MSBFirst BE or LE? |
408 |
* @return int |
409 |
*/ |
410 |
public static final int BuildInteger(byte bytevec[], int offset, |
411 |
boolean MSBFirst) { |
412 |
if (MSBFirst) |
413 |
return BuildIntegerBE(bytevec, offset); |
414 |
else |
415 |
return BuildIntegerLE(bytevec, offset); |
416 |
} |
417 |
|
418 |
/** |
419 |
* Build int out of bytes (in big endian order). |
420 |
* |
421 |
* @param bytevec bytes |
422 |
* @return int |
423 |
*/ |
424 |
public static final int BuildIntegerBE(byte bytevec[]) { |
425 |
return BuildIntegerBE(bytevec, 0); |
426 |
} |
427 |
|
428 |
/** |
429 |
* Build int out of bytes (in little endian order). |
430 |
* |
431 |
* @param bytevec bytes |
432 |
* @return int |
433 |
*/ |
434 |
public static final int BuildIntegerLE(byte bytevec[]) { |
435 |
return BuildIntegerLE(bytevec, 0); |
436 |
} |
437 |
|
438 |
/** |
439 |
* Build int out of bytes. |
440 |
* |
441 |
* @param bytevec bytes |
442 |
* @param MSBFirst BE or LE? |
443 |
* @return int |
444 |
*/ |
445 |
public static final int BuildInteger(byte bytevec[], boolean MSBFirst) { |
446 |
if (MSBFirst) |
447 |
return BuildIntegerBE(bytevec, 0); |
448 |
else |
449 |
return BuildIntegerLE(bytevec, 0); |
450 |
} |
451 |
|
452 |
/** |
453 |
* Build long out of bytes (in big endian order). |
454 |
* |
455 |
* @param bytevec bytes |
456 |
* @param offset byte offset |
457 |
* @return long |
458 |
*/ |
459 |
public static final long BuildLongBE(byte bytevec[], int offset) { |
460 |
return (((long) signedToInt(bytevec[0 + offset]) << 56) |
461 |
| ((long) signedToInt(bytevec[1 + offset]) << 48) |
462 |
| ((long) signedToInt(bytevec[2 + offset]) << 40) |
463 |
| ((long) signedToInt(bytevec[3 + offset]) << 32) |
464 |
| ((long) signedToInt(bytevec[4 + offset]) << 24) |
465 |
| ((long) signedToInt(bytevec[5 + offset]) << 16) |
466 |
| ((long) signedToInt(bytevec[6 + offset]) << 8) | ((long) signedToInt(bytevec[7 + offset]))); |
467 |
} |
468 |
|
469 |
/** |
470 |
* Build long out of bytes (in little endian order). |
471 |
* |
472 |
* @param bytevec bytes |
473 |
* @param offset byte offset |
474 |
* @return long |
475 |
*/ |
476 |
public static final long BuildLongLE(byte bytevec[], int offset) { |
477 |
return (((long) signedToInt(bytevec[7 + offset]) << 56) |
478 |
| ((long) signedToInt(bytevec[6 + offset]) << 48) |
479 |
| ((long) signedToInt(bytevec[5 + offset]) << 40) |
480 |
| ((long) signedToInt(bytevec[4 + offset]) << 32) |
481 |
| ((long) signedToInt(bytevec[3 + offset]) << 24) |
482 |
| ((long) signedToInt(bytevec[2 + offset]) << 16) |
483 |
| ((long) signedToInt(bytevec[1 + offset]) << 8) | ((long) signedToInt(bytevec[0 + offset]))); |
484 |
} |
485 |
|
486 |
/** |
487 |
* Build long out of bytes. |
488 |
* |
489 |
* @param bytevec bytes |
490 |
* @param offset byte offset |
491 |
* @param MSBFirst BE or LE? |
492 |
* @return long |
493 |
*/ |
494 |
public static final long BuildLong(byte bytevec[], int offset, |
495 |
boolean MSBFirst) { |
496 |
if (MSBFirst) |
497 |
return BuildLongBE(bytevec, offset); |
498 |
else |
499 |
return BuildLongLE(bytevec, offset); |
500 |
} |
501 |
|
502 |
/** |
503 |
* Build long out of bytes (in big endian order). |
504 |
* |
505 |
* @param bytevec bytes |
506 |
* @return long |
507 |
*/ |
508 |
public static final long BuildLongBE(byte bytevec[]) { |
509 |
return BuildLongBE(bytevec, 0); |
510 |
} |
511 |
|
512 |
/** |
513 |
* Build long out of bytes (in little endian order). |
514 |
* |
515 |
* @param bytevec bytes |
516 |
* @return long |
517 |
*/ |
518 |
public static final long BuildLongLE(byte bytevec[]) { |
519 |
return BuildLongLE(bytevec, 0); |
520 |
} |
521 |
|
522 |
/** |
523 |
* Build long out of bytes. |
524 |
* |
525 |
* @param bytevec bytes |
526 |
* @param MSBFirst BE or LE? |
527 |
* @return long |
528 |
*/ |
529 |
public static final long BuildLong(byte bytevec[], boolean MSBFirst) { |
530 |
if (MSBFirst) |
531 |
return BuildLongBE(bytevec, 0); |
532 |
else |
533 |
return BuildLongLE(bytevec, 0); |
534 |
} |
535 |
|
536 |
/* |
537 |
* public static final void main(String[] args) { byte[] b = new |
538 |
* byte[4]; b[0] = (byte)0xff; b[1] = (byte)0x7f; |
539 |
* com.bbn.openmap.util.Debug.output("32767="+BuildShortLE(b, 0)); |
540 |
* b[0] = (byte)0x7f; b[1] = (byte)0xff; |
541 |
* com.bbn.openmap.util.Debug.output("32767="+BuildShortBE(b, 0)); |
542 |
* b[1] = (byte)0xff; b[2] = (byte)0xff; b[3] = (byte)0xff; |
543 |
* com.bbn.openmap.util.Debug.output("2147483647="+BuildIntegerBE(b, |
544 |
* 0)); |
545 |
* com.bbn.openmap.util.Debug.output("maxuint="+signedToLong(0xffffffff)); } |
546 |
*/ |
547 |
} |