// ********************************************************************** // // <copyright> // // BBN Technologies // 10 Moulton Street // Cambridge, MA 02138 // (617) 873-8000 // // Copyright (C) BBNT Solutions LLC. All rights reserved. // // </copyright> // ********************************************************************** // // $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/MoreMath.java,v $ // $RCSfile: MoreMath.java,v $ // $Revision: 1.4 $ // $Date: 2004/10/14 18:05:39 $ // $Author: dietrick $ // // ********************************************************************** package com.bbn.openmap; /** * MoreMath provides functions that are not part of the standard Math * class. * <p> * * <pre> * * Functions: * asinh(float x) - hyperbolic arcsine * sinh(float x) - hyperbolic sine * * Need to Implement: * Function Definition * Hyperbolic cosine (eˆx+eˆ-x)/2 * Hyperbolic tangent (eˆx-eˆ-x)/(eˆx+eˆ-x) * Hyperbolic arc cosine 2 log (sqrt((x+1)/2) + sqrt((x-1)/2)) * Hyperbolic arc tangent (log (1+x) - log (1-x))/2 * * </pre> */ public class MoreMath { /** * 2*Math.PI */ final public static transient float TWO_PI = (float) Math.PI * 2.0f; /** * 2*Math.PI */ final public static transient double TWO_PI_D = Math.PI * 2.0d; /** * Math.PI/2 */ final public static transient float HALF_PI = (float) Math.PI / 2.0f; /** * Math.PI/2 */ final public static transient double HALF_PI_D = Math.PI / 2.0d; final public static double EQUIVALENT_TOLERANCE = 0.0000001; // cannot construct private MoreMath() {} /** * Checks if a ~= b. Use this to test equality of floating point * numbers. * <p> * * @param a double * @param b double * @param epsilon the allowable error * @return boolean */ final public static boolean approximately_equal(double a, double b, double epsilon) { return (Math.abs(a - b) <= epsilon); } /** * Checks if a ~= b. Use this to test equality of floating point * numbers against EQUIVALENT_TOLERANCE. * <p> * * @param a double * @param b double * @return boolean */ final public static boolean approximately_equal(double a, double b) { return (Math.abs(a - b) <= EQUIVALENT_TOLERANCE); } /** * Checks if a ~= b. Use this to test equality of floating point * numbers. * <p> * * @param a float * @param b float * @param epsilon the allowable error * @return boolean */ final public static boolean approximately_equal(float a, float b, float epsilon) { return (Math.abs(a - b) <= epsilon); } /** * Hyperbolic arcsin. * <p> * Hyperbolic arc sine: log (x+sqrt(1+x^2)) * * @param x float * @return float asinh(x) */ public static final float asinh(float x) { return (float) Math.log(x + Math.sqrt(x * x + 1)); } /** * Hyperbolic arcsin. * <p> * Hyperbolic arc sine: log (x+sqrt(1+x^2)) * * @param x double * @return double asinh(x) */ public static final double asinh(double x) { return (double) Math.log(x + Math.sqrt(x * x + 1)); } // HACK - are there functions that already exist? /** * Return sign of number. * * @param x short * @return int sign -1, 1 */ public static final int sign(short x) { return (x < 0) ? -1 : 1; } /** * Return sign of number. * * @param x int * @return int sign -1, 1 */ public static final int sign(int x) { return (x < 0) ? -1 : 1; } /** * Return sign of number. * * @param x long * @return int sign -1, 1 */ public static final int sign(long x) { return (x < 0) ? -1 : 1; } /** * Return sign of number. * * @param x float * @return int sign -1, 1 */ public static final int sign(float x) { return (x < 0f) ? -1 : 1; } /** * Return sign of number. * * @param x double * @return int sign -1, 1 */ public static final int sign(double x) { return (x < 0d) ? -1 : 1; } /** * Check if number is odd. * * @param x short * @return boolean */ public static final boolean odd(short x) { return !even(x); } /** * Check if number is odd. * * @param x int * @return boolean */ public static final boolean odd(int x) { return !even(x); } /** * Check if number is odd. * * @param x long * @return boolean */ public static final boolean odd(long x) { return !even(x); } /** * Check if number is even. * * @param x short * @return boolean */ public static final boolean even(short x) { return ((x & 0x1) == 0); } /** * Check if number is even. * * @param x int * @return boolean */ public static final boolean even(int x) { return ((x & 0x1) == 0); } /** * Check if number is even. * * @param x long * @return boolean */ public static final boolean even(long x) { return ((x & 0x1) == 0); } /** * Converts a byte in the range of -128 to 127 to an int in the * range 0 - 255. * * @param b (-128 <= b <= 127) * @return int (0 <= b <= 255) */ public static final int signedToInt(byte b) { return ((int) b & 0xff); } /** * Converts a short in the range of -32768 to 32767 to an int in * the range 0 - 65535. * * @param w (-32768 <= b <= 32767) * @return int (0 <= b <= 65535) */ public static final int signedToInt(short w) { return ((int) w & 0xffff); } /** * Convert an int in the range of -2147483648 to 2147483647 to a * long in the range 0 to 4294967295. * * @param x (-2147483648 <= x <= 2147483647) * @return long (0 <= x <= 4294967295) */ public static final long signedToLong(int x) { return ((long) x & 0xFFFFFFFFL); } /** * Converts an int in the range of 0 - 65535 to an int in the * range of 0 - 255. * * @param w int (0 <= w <= 65535) * @return int (0 <= w <= 255) */ public static final int wordToByte(int w) { return w >> 8; } /** * Build short out of bytes (in big endian order). * * @param bytevec bytes * @param offset byte offset * @return short */ public static final short BuildShortBE(byte bytevec[], int offset) { return (short) (((int) (bytevec[0 + offset]) << 8) | (signedToInt(bytevec[1 + offset]))); } /** * Build short out of bytes (in little endian order). * * @param bytevec bytes * @param offset byte offset * @return short */ public static final short BuildShortLE(byte bytevec[], int offset) { return (short) (((int) (bytevec[1 + offset]) << 8) | (signedToInt(bytevec[0 + offset]))); } /** * Build short out of bytes. * * @param bytevec bytes * @param offset byte offset * @param MSBFirst BE or LE? * @return short */ public static final short BuildShort(byte bytevec[], int offset, boolean MSBFirst) { if (MSBFirst) { return (BuildShortBE(bytevec, offset)); } else { return (BuildShortLE(bytevec, offset)); } } /** * Build short out of bytes (in big endian order). * * @param bytevec bytes * @param MSBFirst BE or LE? * @return short */ public static final short BuildShortBE(byte bytevec[], boolean MSBFirst) { return BuildShortBE(bytevec, 0); } /** * Build short out of bytes (in little endian order). * * @param bytevec bytes * @param MSBFirst BE or LE? * @return short */ public static final short BuildShortLE(byte bytevec[], boolean MSBFirst) { return BuildShortLE(bytevec, 0); } /** * Build short out of bytes. * * @param bytevec bytes * @param MSBFirst BE or LE? * @return short */ public static final short BuildShort(byte bytevec[], boolean MSBFirst) { return BuildShort(bytevec, 0, MSBFirst); } /** * Build int out of bytes (in big endian order). * * @param bytevec bytes * @param offset byte offset * @return int */ public static final int BuildIntegerBE(byte bytevec[], int offset) { return (((int) (bytevec[0 + offset]) << 24) | (signedToInt(bytevec[1 + offset]) << 16) | (signedToInt(bytevec[2 + offset]) << 8) | (signedToInt(bytevec[3 + offset]))); } /** * Build int out of bytes (in little endian order). * * @param bytevec bytes * @param offset byte offset * @return int */ public static final int BuildIntegerLE(byte bytevec[], int offset) { return (((int) (bytevec[3 + offset]) << 24) | (signedToInt(bytevec[2 + offset]) << 16) | (signedToInt(bytevec[1 + offset]) << 8) | (signedToInt(bytevec[0 + offset]))); } /** * Build int out of bytes. * * @param bytevec bytes * @param offset byte offset * @param MSBFirst BE or LE? * @return int */ public static final int BuildInteger(byte bytevec[], int offset, boolean MSBFirst) { if (MSBFirst) return BuildIntegerBE(bytevec, offset); else return BuildIntegerLE(bytevec, offset); } /** * Build int out of bytes (in big endian order). * * @param bytevec bytes * @return int */ public static final int BuildIntegerBE(byte bytevec[]) { return BuildIntegerBE(bytevec, 0); } /** * Build int out of bytes (in little endian order). * * @param bytevec bytes * @return int */ public static final int BuildIntegerLE(byte bytevec[]) { return BuildIntegerLE(bytevec, 0); } /** * Build int out of bytes. * * @param bytevec bytes * @param MSBFirst BE or LE? * @return int */ public static final int BuildInteger(byte bytevec[], boolean MSBFirst) { if (MSBFirst) return BuildIntegerBE(bytevec, 0); else return BuildIntegerLE(bytevec, 0); } /** * Build long out of bytes (in big endian order). * * @param bytevec bytes * @param offset byte offset * @return long */ public static final long BuildLongBE(byte bytevec[], int offset) { return (((long) signedToInt(bytevec[0 + offset]) << 56) | ((long) signedToInt(bytevec[1 + offset]) << 48) | ((long) signedToInt(bytevec[2 + offset]) << 40) | ((long) signedToInt(bytevec[3 + offset]) << 32) | ((long) signedToInt(bytevec[4 + offset]) << 24) | ((long) signedToInt(bytevec[5 + offset]) << 16) | ((long) signedToInt(bytevec[6 + offset]) << 8) | ((long) signedToInt(bytevec[7 + offset]))); } /** * Build long out of bytes (in little endian order). * * @param bytevec bytes * @param offset byte offset * @return long */ public static final long BuildLongLE(byte bytevec[], int offset) { return (((long) signedToInt(bytevec[7 + offset]) << 56) | ((long) signedToInt(bytevec[6 + offset]) << 48) | ((long) signedToInt(bytevec[5 + offset]) << 40) | ((long) signedToInt(bytevec[4 + offset]) << 32) | ((long) signedToInt(bytevec[3 + offset]) << 24) | ((long) signedToInt(bytevec[2 + offset]) << 16) | ((long) signedToInt(bytevec[1 + offset]) << 8) | ((long) signedToInt(bytevec[0 + offset]))); } /** * Build long out of bytes. * * @param bytevec bytes * @param offset byte offset * @param MSBFirst BE or LE? * @return long */ public static final long BuildLong(byte bytevec[], int offset, boolean MSBFirst) { if (MSBFirst) return BuildLongBE(bytevec, offset); else return BuildLongLE(bytevec, offset); } /** * Build long out of bytes (in big endian order). * * @param bytevec bytes * @return long */ public static final long BuildLongBE(byte bytevec[]) { return BuildLongBE(bytevec, 0); } /** * Build long out of bytes (in little endian order). * * @param bytevec bytes * @return long */ public static final long BuildLongLE(byte bytevec[]) { return BuildLongLE(bytevec, 0); } /** * Build long out of bytes. * * @param bytevec bytes * @param MSBFirst BE or LE? * @return long */ public static final long BuildLong(byte bytevec[], boolean MSBFirst) { if (MSBFirst) return BuildLongBE(bytevec, 0); else return BuildLongLE(bytevec, 0); } /** * lat just less than 90 degrees. * * @param val lat value to test * @return value just less than... */ public static double latJLT90(double val) { return justLessThan(val, 90, .00001); } /** * Return value just less than provided value, in positive and negative * terms. * * @param val value to test * @param lessThan abs value to test against * @param howMuchLess how much to move val to zero based on comparison to * less than * @return val, or adjusted val */ public static double justLessThan(double val, double lessThan, double howMuchLess) { if (val >= lessThan) { val = lessThan = howMuchLess; } else if (val <= -lessThan) { val = -lessThan + howMuchLess; } return val; } /* * public static final void main(String[] args) { byte[] b = new * byte[4]; b[0] = (byte)0xff; b[1] = (byte)0x7f; * com.bbn.openmap.util.Debug.output("32767="+BuildShortLE(b, 0)); * b[0] = (byte)0x7f; b[1] = (byte)0xff; * com.bbn.openmap.util.Debug.output("32767="+BuildShortBE(b, 0)); * b[1] = (byte)0xff; b[2] = (byte)0xff; b[3] = (byte)0xff; * com.bbn.openmap.util.Debug.output("2147483647="+BuildIntegerBE(b, * 0)); * com.bbn.openmap.util.Debug.output("maxuint="+signedToLong(0xffffffff)); } */ }