/**

This library is now under construction.

まだ開発中の不完全バージョンです。

This is a library for floated-pointed-number. On J2ME, we can't use either "double" nor "float", so we cannot use pointed-number at default.

On the case of J-PHONE's JavaAppli, J-PHONE's JBlend (that is the platform of J-PHONE's Java apolicatoins) has FixedPointed Class and with it we can use pointed-number at a brief accuracy. J-PHONE is a Japanese campany of cellur phones and releases phones that can run Java applications. For more information, see http://www.dp.j-phone.com/.

On the other case, in addition to the J-PHONE's case of requiring more accuracy, we can use MathFP library. This library is made in 64bit and on the most of the cases we can manage with this library.

But both of these libraries are constructed on FixedPoint method, so on some cases we across to calcuration errors. For example, "10000 * 0.0001" results "0.9997" on MathFP. This is caused by a rounded error and buiding on FixedPoint method we cannot avoid it.

To avoid rounded error, the library should be built on FloatedPoint method. For my searching, I found that there existed no pointed-number library that is built on FloatedPoint method. So I decided to make it by myself, and now I released this library.

You can use this library freely almost all of the cases, but only when you customize this library and republish it, please tell me and also tell the users of your customized library the truth that it is a customization of this original library. It is not necessary to publish with sources, which is the deference of GPL. I hope this library will become a much help to you.

Thank you. by rarul

An instance of this library uses one long and an int. And most of the method will cost much machine power. So when you think of using this library on a poor platform, I advise you should not use this library. */ public class myMath extends Object { private long fp ; private int ip ; /** Accuracy of this library. You use 1.23456789 valid pointed-number on the default. For most cases, you should not change this variable. */ public static final int prec = 9 ; /** Instance of mathematical e. That is almost 2.718281828 */ public static final myMath CON_E = new myMath("2.718281828") ; /** Instance os mathmatical PI. That is almost 3.141592654 */ public static final myMath CON_PI= new myMath("3.141592654") ; /** Default constructor. This make "0". */ public myMath () { fp = ip = 0 ; return ; } /** Construct with setting number. @see #set(long). */ public myMath( long in){ set(in) ; } /** Construct with setting number. @see #set(String). */ public myMath( String str){ set( str) ; } /** Construct with setting number. @see #set(long,int). */ public myMath( long in, int i){ set( in, i) ; } /** Make clone of b. @see #set(myMath). */ public myMath( myMath b){ set( b) ; return ; } /** Copy b. @see #myMath( myMath). */ public void set( myMath b){ this.fp = b.fp ; this.ip = b.ip ; return ; } /** make [in] number. if in==100 then make 1.00E2 @see #myMath( long). */ public void set( long in){ if( in == 0){ fp = ip = 0 ; return ; } ip = prec - 1; fp = in ; Regulate () ; return ; } /** make in*10^i number. if in=100 and i=2 then make 1.00E4 @see #myMath( long, int). */ public void set( long in, int i){ if( in == 0){ fp = ip = 0 ; return ; } ip = prec + i - 1; fp = in ; Regulate () ; return ; } /** make [str] number. formats are (num) or (num"E"int)
(let num "int.int" or "int")
for examble
1.1, 10, 10E1, 1.1E0, 0.1E2,
1.23E-12 ect.. @see #myMath( String). */ public void set( String str){ if( str.equals("0")){ fp = ip = 0 ; return ; } int i = str.indexOf('E') ; long ii ; if( i>=0){ // 有効数字表示の場合、E以降の数字より桁数をずらす ip += Integer.parseInt( str.substring( i+1)) ; str = str.substring( 0, i) ; } i = str.indexOf('.') ; if( i<0){ // 小数ではない場合 ii = Long.parseLong( str) ; } else { // 小数の場合 ip -= str.substring( i+1).length() ; ii = Long.parseLong( str.substring(0,i) + str.substring(i+1)) ; } ip = ip + prec - 1; fp = ii ; Regulate () ; return ; } /** Add b to this and set the result. So this method is as same as following. ("a" means the instance to call this method.)

a = a + b
@see #add( myMath, myMath) */ public void add( myMath b){ long tmp = b.fp ; long i ; if( this.ip == b.ip){ this.fp += tmp ; } else if( this.ip > b.ip){ i = power( 10, this.ip-b.ip-1) ; if( tmp>0){ tmp += i*5 ; } else { tmp -= i*5 ; } tmp /= i*10 ; this.fp += tmp ; } else { i = power( 10, b.ip-this.ip-1) ; if( this.fp>0){ this.fp += i*5 ; } else { this.fp -= i*5 ; } this.fp /= i*10 ; this.fp += tmp ; this.ip = b.ip ; } Regulate () ; return ; } /** Sub b to this and set the result. So this method is as same as following. ("a" means the instance to call this method.)
a = a - b
@see #sub( myMath, myMath) */ public void sub( myMath b){ long tmp = b.fp ; long i ; if( this.ip == b.ip){ this.fp -= tmp ; } else if( this.ip > b.ip){ i = power( 10, this.ip-b.ip-1) ; if( tmp>0){ tmp += i*5 ; } else { tmp -= i*5 ; } tmp /= i*10 ; this.fp -= tmp ; } else { i = power( 10, b.ip-this.ip-1) ; if( this.fp>0){ this.fp += i*5 ; } else { this.fp -= i*5 ; } this.fp /= i*10 ; this.fp -= tmp ; this.ip = b.ip ; } Regulate () ; return ; } /** Mul b to this and set the result. So this method is as same as following. ("a" means the instance to call this method.)
a = a * b
@see #mul( myMath, myMath) */ public void mul( myMath b){ this.fp = this.fp * b.fp ; this.ip = this.ip + b.ip - prec + 1 ; Regulate () ; return ; } /** Div this by b and set the result. So this method is as same as following. ("a" means the instance to call this method.)
a = a / b
@see #div( myMath, myMath) */ public void div( myMath b){ long tmp = this.fp ; tmp *= power( 10, prec-1) ; tmp /= b.fp ; this.fp = tmp ; this.ip = this.ip - b.ip ; Regulate () ; return ; } /** Add a to b and return the result. So this method is as same as following.
return a + b
@see #add( myMath) */ public static myMath add( myMath a, myMath b){ myMath tmp = new myMath( a) ; tmp.add(b) ; return tmp ; } /** Sub b from a and return the result. So this method is as same as following.
return a - b
@see #sub( myMath) */ public static myMath sub( myMath a, myMath b){ myMath tmp = new myMath( b) ; tmp.fp = -b.fp ; tmp.add(a) ; return tmp ; } /** Mul a to b and return the result. So this method is as same as following.
return a * b
@see #mul( myMath) */ public static myMath mul( myMath a, myMath b){ myMath tmp = new myMath( a) ; tmp.mul(b) ; return tmp ; } /** Div a by b and return the result. So this method is as same as following.
return a / b
@see #div( myMath) */ public static myMath div( myMath a, myMath b){ myMath tmp = new myMath( a) ; tmp.div(b) ; return tmp ; } /** Calculate n!. n! is as following
n! = n * (n-1)! , (n>=2)
n! = 1 , ( n = 0, 1)
*/ public static long fact( int n){ long tmp = 1 ; for( ;n>0; n--){ tmp *= n ; } return tmp ; } /** Calculate n^m and return it. n^m is as following
n^m = n * n^(m-1) , (m>=1)
n^0 = 1
*/ public static long power( int n, int m){ if( m<0){ return 0 ; } long tmp = 1 ; for( ; m>0; m--){ tmp *= n ; } return tmp ; } /** If n>=m then return true. This method will return earlier than sub( myMath, myMath) or div( myMath, myMath). @see #sub( myMath, myMath) @see #div( myMath, myMath) */ public static boolean max( myMath n, myMath m){ if( n.fp==0){ if( m.fp < 0){ return true ; } else { return false ; } } else if( n.fp > 0){ if( m.fp >= 0){ if( n.ip > m.ip){ return true ; } else if( n.ip < m.ip){ return false ; } else { if( m.fp >= n.fp){ return true ; } else { return false ; } } } else { return true ; } } else { if( m.fp >= 0){ return false ; } else { if( n.ip > m.ip){ return false ; } else if( n.ip < m.ip ){ return true ; } else { if( n.fp >= m.fp){ return true ; } else { return false ; } } } } } /** Return the integer part. n's integer part means max integer p, as following.
n = p + q , ( 0<=q<1)
For example, integer part of 5.01 is 5, -3,22 -4, etc.
*/ public long getInteger () { int ii = prec - ip - 1 ; long tmp = fp ; if( ii>0){ tmp = power( 10, ii) ; ii = (int)(fp/tmp) ; if( ii*tmp == fp){ return ii ; } else { if( fp < 0){ ii-- ; } return ii ; } } else { return power( 10, -ii) ; } } /** Print in a format of using "E".
That is, [111] -> "1.11E2" , [12.34] -> "1.234E1" , etc. @see #toStringD */ public String toString () { if( fp==0){ return "0" ; } else { String str = String.valueOf( fp) ; if( fp>0){ return str.substring(0,1) + "."+str.substring(1)+"E"+ip ; } else { return str.substring(0,2) + "."+str.substring(2)+"E"+ip ; } } } /** Print in a format of non using "E"
@see #toString */ public String toStringD () { // 有効数字じゃないふつうの表示に加工する if( fp==0){ return "0" ; } else { if( ip>=prec-1){ // 小数点が隠れるほど数字がでかい場合。 // 100000000 など return String.valueOf( fp*power( 10, ip-prec+1)) ; } else if( ip>=0){ // 小数点が隠れない程度の数の場合 String str = String.valueOf( fp) ; if( fp>=0){ // 正の場合 // 1000 など return str.substring(0,ip+1) + "."+str.substring(ip+1) ; } else { // 負の場合 // -10000 など return str.substring(0,ip+2) + "."+str.substring(ip+2) ; } } else { // 小数が一番前に来るくらい小さい数の場合 long tmp = fp ; int ii = ip ; if( tmp > 0){ tmp += 5*power( 10, -ii-1) ; if( tmp >= power( 10, prec)){ tmp /= 10 ; ii ++ ; if( ii>=0){ String str = String.valueOf( tmp) ; return str.substring(0,ii+1) + "."+str.substring(ii+1) ; } } if( ii < -prec){ // 通常表示では表現できないくらい小さい数字の場合 return "0." + String.valueOf(power( 10, 8)).substring( 1) ; } else { return "0." + String.valueOf(power( 10, -ii-1)).substring( 1) + String.valueOf(tmp).substring(0,prec+ii) ; } } else { tmp -= 5*power( 10, -ii-1) ; if( -tmp >= power( 10, prec)){ tmp /= 10 ; ii ++ ; if( ii>=0){ String str = String.valueOf( tmp) ; return str.substring(0,ip+2) + "."+str.substring(ip+2) ; } } if( ii < -prec){ // 通常表示では表現できないくらい小さい数字の場合 return "-0." + String.valueOf(power( 10, 8)).substring( 1) ; } else { return "-0." + String.valueOf(power( 10, -ii-1)).substring( 1) + String.valueOf(tmp).substring(1,prec+ii+1) ; } } } } } private void Regulate () { int len = java.lang.String.valueOf( fp).length() ; if( fp == 0){ ip = 0 ; return ; } else if( fp<0){ // 負の数の場合は、「-」の分を除外する必要あり len-- ; } if( len==prec){ // lenの桁数はすでに正規化されたものと等しい return ; } else if( len>prec){ // lenの桁数は正規化数よりも多い、有効数字部を削って指数部をあげる必要あり long i ; len -= prec ; ip += len ; i = power( 10, len-1) ; if( fp>0){ fp += i*5 ; } else { fp -= i*5 ; } fp /= i*10 ; return ; } else { // lenの桁数は正規化数よりも少ない、有効数字部を増やして指数部をさげる必要あり len = prec - len ; ip -= len ; fp *= power( 10, len) ; return ; } } public myMath getDecimal () { myMath mm = new myMath( getInteger()) ; mm.sub( this) ; mm.fp = -mm.fp ; return mm ; } public void Mod( myMath b){ myMath mm = div( this, b) ; mm.set( mm.getInteger()) ; mm.mul(b) ; sub( mm) ; return ; } public static myMath Mod( myMath a, myMath b){ myMath mm = div( a, b) ; mm.set( mm.getInteger()) ; mm.mul(b) ; mm.sub(a) ; mm.fp = -mm.fp ; return mm ; } public void cos () { myMath pi2 = new myMath( CON_PI) ; myMath fx ; pi2.fp *= 2 ; if( fp < 0){ // cosは偶関数 fp = -fp ; } if( max( this, pi2)){ // 0 <= this < 2pi にする。 Mod( pi2) ; } if( max( this, CON_PI)){ // pi <= this < 2piでは、 // 2pi-this に等しい。(cosの性質) sub( pi2) ; fp = -fp ; } // テイラー展開をするために展開の中心0からの距離をできるだけ近くするため(誤差を減らすため)に、 // cos -> sin の変換をする。sin( x + pi/4) = cos( x) を利用する。 pi2.fp /= 4 ; add( pi2) ; pi2.set( this) ; // sin( this) でテイラー展開をする。 -pi/4 < this <= pi/4 を満たす fx = new myMath( this) ; for( int i=2; i<17; i+=4){ fx.mul( this) ; fx.fp /= i*(i+1) ; fx.mul( this) ; pi2.sub( fx) ; fx.mul( this) ; fx.fp /= (i+2)*(i+3) ; fx.mul( this) ; pi2.add( fx) ; } set( pi2) ; return ; } public void sin () { CON_PI.fp /= 2 ; sub( CON_PI) ; CON_PI.fp *= 2 ; // sin( x) = cos( x-PI/2) cos() ; return ; } }