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 046package jj2000.j2k.util; 047 048/** 049 * This class contains a collection of utility methods fro mathematical 050 * operations. All methods are static. 051 * */ 052public class MathUtil { 053 054 /** 055 * Method that calculates the floor of the log, base 2, 056 * of 'x'. The calculation is performed in integer arithmetic, 057 * therefore, it is exact. 058 * 059 * @param x The value to calculate log2 on. 060 * 061 * @return floor(log(x)/log(2)), calculated in an exact way. 062 * */ 063 public static int log2(int x) { 064 int y,v; 065 // No log of 0 or negative 066 if (x <= 0) { 067 throw new IllegalArgumentException(""+x+" <= 0"); 068 } 069 // Calculate log2 (it's actually floor log2) 070 v = x; 071 y = -1; 072 while (v>0) { 073 v >>=1; 074 y++; 075 } 076 return y; 077 } 078 079 /** 080 * Method that calculates the Least Common Multiple (LCM) of two strictly 081 * positive integer numbers. 082 * 083 * @param x1 First number 084 * 085 * @param x2 Second number 086 * */ 087 public static final int lcm(int x1,int x2) { 088 if(x1<=0 || x2<=0) { 089 throw new IllegalArgumentException("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("Cannot find the least common multiple of numbers "+ 108 x1+" and "+x2); 109 } 110 111 /** 112 * Method that calculates the Least Common Multiple (LCM) of several 113 * positive integer numbers. 114 * 115 * @param x Array containing the numbers. 116 * */ 117 public static final int lcm(int[] x) { 118 if(x.length<2) { 119 throw new Error("Do not use this method if there are less than"+ 120 " two numbers."); 121 } 122 int tmp = lcm(x[x.length-1],x[x.length-2]); 123 for(int i=x.length-3; i>=0; i--) { 124 if(x[i]<=0) { 125 throw new IllegalArgumentException("Cannot compute the least "+ 126 "common multiple of "+ 127 "several numbers where "+ 128 "one, at least,"+ 129 "is negative."); 130 } 131 tmp = lcm(tmp,x[i]); 132 } 133 return tmp; 134 } 135 136 /** 137 * Method that calculates the Greatest Common Divisor (GCD) of two 138 * positive integer numbers. 139 * */ 140 public static final int gcd(int x1,int x2) { 141 if(x1<0 || x2<0) { 142 throw new IllegalArgumentException("Cannot compute the GCD "+ 143 "if one integer is negative."); 144 } 145 int a,b,g,z; 146 147 if(x1>x2) { 148 a = x1; 149 b = x2; 150 } else { 151 a = x2; 152 b = x1; 153 } 154 155 if(b==0) return 0; 156 157 g = b; 158 while (g!=0) { 159 z= a%g; 160 a = g; 161 g = z; 162 } 163 return a; 164 } 165 166 /** 167 * Method that calculates the Greatest Common Divisor (GCD) of several 168 * positive integer numbers. 169 * 170 * @param x Array containing the numbers. 171 * */ 172 public static final int gcd(int[] x) { 173 if(x.length<2) { 174 throw new Error("Do not use this method if there are less than"+ 175 " two numbers."); 176 } 177 int tmp = gcd(x[x.length-1],x[x.length-2]); 178 for(int i=x.length-3; i>=0; i--) { 179 if(x[i]<0) { 180 throw new IllegalArgumentException("Cannot compute the least "+ 181 "common multiple of "+ 182 "several numbers where "+ 183 "one, at least,"+ 184 "is negative."); 185 } 186 tmp = gcd(tmp,x[i]); 187 } 188 return tmp; 189 } 190}