/*
This file is part of the software framework JStatCom,
a library for building applications for data based analysis.
Copyright (C) 2000-2005 Alexander Benkwitz, Markus Kraetzig
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
*/
package com.jstatcom.util;
/**
* This class is a collection of some mathematical functions. It can be used in
* addition to the Math class.
*
* @author A. Benkwitz, Markus Kraetzig
*/
public final class UMath {
/**
* Private constructor to avoid invocation.
*/
private UMath() {
}
/**
* Transforms arbitrary double values to a
* double in the interval (-10,-1] or [1,10) and a power of
* 10. It breaks number to a number of the form #.####... and a power of 10.
* { mant,pow } = base10(arg) with mant * 10^pow == arg
* returnValue[0]=mant, returnValue[1]=pow.
* If arg is NaN or +/-INF, then {arg, 0} is
* returned.
*
* @param arg
* the number to break
*
* @return two dimensional double array
*
* double[0] the mantisse
* double[1] the power of 10
*
*/
public static double[] base10(double arg) {
if (arg == Double.POSITIVE_INFINITY || arg == Double.NEGATIVE_INFINITY)
return new double[] { arg, 0 };
if (!(arg <= 0 || arg > 0)) // must be NaN then
return new double[] { Double.NaN, 0 };
if (arg == 0)
return new double[] { 0, 0 };
double a = Math.abs(arg);
int i = 0;
if (a < 1) {
// case: absolute value of arg smaller than 1
i = 1;
while (a * Math.pow(10, ++i) < 10)
;
i--;
return new double[] { round(arg * Math.pow(10, i), 18 - i), -1 * i };
}
if (a < 10) {
// case: absolute value of arg smaller than 10, but bigger or equal
// 1
return new double[] { arg, 0 };
}
// case: absolute value of arg bigger or equal 10
i = 1;
while (Math.pow(10, ++i) < a)
;
i--;
return new double[] { (arg / Math.pow(10, i)), i };
}
/**
* Computes the closest multiple of unit for
* value. If value is just in the middle
* between two multiples of unit, the higher multiple is
* choosen, for example 15 == closestMultiple(13, 5),
* 10 == closestMultiple(12, 5), 8 == closestMultiple(7, 4).
*
* @param value
* defines a closest multiple of unit
* @param unit
* defines the steps
* @return closest multiple of unit for value,
* returns value if (unit == 1), returns 0
* if (unit == 0)
*/
public static int closestMultiple(int value, int unit) {
if (unit == 0)
return 0;
if (unit == 1 || unit == -1)
return value;
double uu = Math.abs(unit);
return (int) round(value / uu, 0) * unit * sign(unit);
}
/**
* Rounds the arg to a number with n decimal
* digits, for example 2.368=round(2.367849,3) If
* arg is NaN or +/-INF, then arg is returned.
*
* @param arg
* the number to round
* @param n
* the number of decimal digits to round for
*
* @return the rounded number
*/
public static double round(double arg, int n) {
if (arg == Double.POSITIVE_INFINITY || arg == Double.NEGATIVE_INFINITY)
return arg;
if (!(arg <= 0 || arg > 0)) // must be NaN then
return Double.NaN;
return Math.round(Math.pow(10, n) * arg) / Math.pow(10, n);
}
/**
* Returns -1 if arg is smaller than zero and 1 if it is
* greater or equal to zero.
*
* @param arg
* the number to check the sign for
* @return -1 if (arg < 0), otherwise 1
*/
public static int sign(int arg) {
if (arg < 0)
return -1;
return 1;
}
}
Ads help maintain this website.