001: /*
002: * $RCSfile: MathUtil.java,v $
003: * $Revision: 1.1 $
004: * $Date: 2005/02/11 05:02:25 $
005: * $State: Exp $
006: *
007: * Class: MathUtil
008: *
009: * Description: Utility mathematical methods
010: *
011: *
012: *
013: * COPYRIGHT:
014: *
015: * This software module was originally developed by Raphaël Grosbois and
016: * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
017: * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David
018: * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research
019: * Centre France S.A) in the course of development of the JPEG2000
020: * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
021: * software module is an implementation of a part of the JPEG 2000
022: * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
023: * Systems AB and Canon Research Centre France S.A (collectively JJ2000
024: * Partners) agree not to assert against ISO/IEC and users of the JPEG
025: * 2000 Standard (Users) any of their rights under the copyright, not
026: * including other intellectual property rights, for this software module
027: * with respect to the usage by ISO/IEC and Users of this software module
028: * or modifications thereof for use in hardware or software products
029: * claiming conformance to the JPEG 2000 Standard. Those intending to use
030: * this software module in hardware or software products are advised that
031: * their use may infringe existing patents. The original developers of
032: * this software module, JJ2000 Partners and ISO/IEC assume no liability
033: * for use of this software module or modifications thereof. No license
034: * or right to this software module is granted for non JPEG 2000 Standard
035: * conforming products. JJ2000 Partners have full right to use this
036: * software module for his/her own purpose, assign or donate this
037: * software module to any third party and to inhibit third parties from
038: * using this software module for non JPEG 2000 Standard conforming
039: * products. This copyright notice must be included in all copies or
040: * derivative works of this software module.
041: *
042: * Copyright (c) 1999/2000 JJ2000 Partners.
043: * */
044:
045: package jj2000.j2k.util;
046:
047: /**
048: * This class contains a collection of utility methods fro mathematical
049: * operations. All methods are static.
050: * */
051: public class MathUtil {
052:
053: /**
054: * Method that calculates the floor of the log, base 2,
055: * of 'x'. The calculation is performed in integer arithmetic,
056: * therefore, it is exact.
057: *
058: * @param x The value to calculate log2 on.
059: *
060: * @return floor(log(x)/log(2)), calculated in an exact way.
061: * */
062: public static int log2(int x) {
063: int y, v;
064: // No log of 0 or negative
065: if (x <= 0) {
066: throw new IllegalArgumentException("" + x + " <= 0");
067: }
068: // Calculate log2 (it's actually floor log2)
069: v = x;
070: y = -1;
071: while (v > 0) {
072: v >>= 1;
073: y++;
074: }
075: return y;
076: }
077:
078: /**
079: * Method that calculates the Least Common Multiple (LCM) of two strictly
080: * positive integer numbers.
081: *
082: * @param x1 First number
083: *
084: * @param x2 Second number
085: * */
086: public static final int lcm(int x1, int x2) {
087: if (x1 <= 0 || x2 <= 0) {
088: throw new IllegalArgumentException(
089: "Cannot compute the least "
090: + "common multiple of two "
091: + "numbers if one, at least,"
092: + "is negative.");
093: }
094: int max, min;
095: if (x1 > x2) {
096: max = x1;
097: min = x2;
098: } else {
099: max = x2;
100: min = x1;
101: }
102: for (int i = 1; i <= min; i++) {
103: if ((max * i) % min == 0) {
104: return i * max;
105: }
106: }
107: throw new Error(
108: "Cannot find the least common multiple of numbers "
109: + x1 + " and " + x2);
110: }
111:
112: /**
113: * Method that calculates the Least Common Multiple (LCM) of several
114: * positive integer numbers.
115: *
116: * @param x Array containing the numbers.
117: * */
118: public static final int lcm(int[] x) {
119: if (x.length < 2) {
120: throw new Error(
121: "Do not use this method if there are less than"
122: + " two numbers.");
123: }
124: int tmp = lcm(x[x.length - 1], x[x.length - 2]);
125: for (int i = x.length - 3; i >= 0; i--) {
126: if (x[i] <= 0) {
127: throw new IllegalArgumentException(
128: "Cannot compute the least "
129: + "common multiple of "
130: + "several numbers where "
131: + "one, at least," + "is negative.");
132: }
133: tmp = lcm(tmp, x[i]);
134: }
135: return tmp;
136: }
137:
138: /**
139: * Method that calculates the Greatest Common Divisor (GCD) of two
140: * positive integer numbers.
141: * */
142: public static final int gcd(int x1, int x2) {
143: if (x1 < 0 || x2 < 0) {
144: throw new IllegalArgumentException(
145: "Cannot compute the GCD "
146: + "if one integer is negative.");
147: }
148: int a, b, g, z;
149:
150: if (x1 > x2) {
151: a = x1;
152: b = x2;
153: } else {
154: a = x2;
155: b = x1;
156: }
157:
158: if (b == 0)
159: return 0;
160:
161: g = b;
162: while (g != 0) {
163: z = a % g;
164: a = g;
165: g = z;
166: }
167: return a;
168: }
169:
170: /**
171: * Method that calculates the Greatest Common Divisor (GCD) of several
172: * positive integer numbers.
173: *
174: * @param x Array containing the numbers.
175: * */
176: public static final int gcd(int[] x) {
177: if (x.length < 2) {
178: throw new Error(
179: "Do not use this method if there are less than"
180: + " two numbers.");
181: }
182: int tmp = gcd(x[x.length - 1], x[x.length - 2]);
183: for (int i = x.length - 3; i >= 0; i--) {
184: if (x[i] < 0) {
185: throw new IllegalArgumentException(
186: "Cannot compute the least "
187: + "common multiple of "
188: + "several numbers where "
189: + "one, at least," + "is negative.");
190: }
191: tmp = gcd(tmp, x[i]);
192: }
193: return tmp;
194: }
195: }
|