⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hfloat.java

📁 j2me is based on j2mepolish, client & server for mobile application. menu sample
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * Created on 27-Nov-2005 at 14:08:51.
 *
 * HFloat - floating point arithmetics for mobile devices
 *
 * Copyright (c) 2005 Horst Jaeger / Medienkonzepte GbR, Cologne, Germany
 *
 * This file is part of J2ME Polish.
 *
 * HFloat is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * HFloat 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 General Public License for more details.
 * 
 * You can receive a copy of the GNU General Public License
 * if you write to the Free Software Foundation, Inc., 
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * 
 * Commercial licenses are also available indpendently of J2ME Polish, please mail
 * hfloat@medienkonzepte.de for details.
 * You can also use HFloat commercially when you have obtained a commercial
 * license of J2ME Polish. 
 *
 */
 
package de.enough.polish.math;

/*
 * This class implements floating point arithmetics and some maths. HFloats can be constructed from int like in new HFloat(3) or from String like in new HFloat("-3.14E-2") which means -0.0314 . If you don't want to use the E-Syntax, type new HFloat("-0.0314") instead.
 * 
 * The first argument of each operation is the HFloat object itself. E.g. if you want to know what 2.3 * 4.7 is, type
 * System.out.println((new HFloat("2.3")).mlt(new HFloat("4.7")).toString()); this yields "1.08100000E1" which is
 * just another way of writing 10.81 . HFloat will always use the scientific output format - there's no way of telling it
 * to use a different one.
 * 
 * In case of any invalid operation, the result will be NaN (Not A Number) . We did not want to waste Memory on additinal
 * classes so we did not define any HFloat-Exceptions.
 * 
 * Because a HFloat may be invalid, it can't be cast to int - it can be cast to Integer instead, using the toInteger()
 * function. The result will be null if the HFloat is NAN.
 * 
 * Two HFloats x and y can be compared using the cmp-Function. The result of x.cmp(y) will be -1 if x < y, 0 if x == y
 * and +1 if x > y . You can give a tolerance value eps as well using x.softCmp(y, eps, true) or x.softCmp(y, eps, false).
 * Then x and y will be considered equal if they differ less than or no more than eps respectively. The cmp and softCmp
 * functions both yield Integer instead of int so the result can be null in case of NaNs.
 * 
 * There are lots of examples about how to use HFloats in the HFloat.java source file as well.
 */public class HFloat extends Object{
  
//Internal

  protected class HFloatHTaylor extends Object implements HTaylor{
    
    public HFloatHTaylor(              ){init(        -1);}
    public HFloatHTaylor(int werBinIchP){init(werBinIchP);}
    
    protected void init(int werBinIchA){
      this.werBinIchP = werBinIchA;
      this.altN       = 0;
      this.altCoeff   = new HFloat(1); // haengt aus purem Zufall nicht von von werBinIchP ab
    }

    public HFloat coeff(int n){
      switch(this.werBinIchP){
        case ASIN_HTAYLOR:
          if(n < this.altN) init(this.werBinIchP);
          for(int m = this.altN + 1; m <= n; ++m){
            int m2 = 2 * m;
            this.altCoeff = this.altCoeff.mlt(m2 - 1).div(m2);      
          }
          this.altN = n;      
          return this.altCoeff.div(2 * n + 1);  
        case ATAN_HTAYLOR:
          if(n % 2 == 0) return (new HFloat( 1)).div(2 * n + 1);
          else           return (new HFloat(-1)).div(2 * n + 1);
        case COS_HTAYLOR:
          if(n < this.altN) init(this.werBinIchP);
          for(int m = this.altN + 1; m <= n; ++m){
            int m2 = 2 * m;
            this.altCoeff = this.altCoeff.div(m2 * (1 - m2));      
          }
          this.altN = n;      
          return this.altCoeff;  
        case EXP_HTAYLOR:
          if(n < this.altN) init(this.werBinIchP);
          for(int m = this.altN + 1; m <= n; ++m) this.altCoeff = this.altCoeff.div(m);      
          this.altN = n;      
          return this.altCoeff;  
        case LN_HTAYLOR:
          if(n % 2 == 0) return (new HFloat( 1)).div(n + 1);
          else           return (new HFloat(-1)).div(n + 1);
        case SIN_HTAYLOR:
         if(n < this.altN) init(this.werBinIchP);
         for(int m = this.altN + 1; m <= n; ++m){
           int m2 = 2 * m;
           this.altCoeff = this.altCoeff.div(-m2 * (1 + m2));      
         }
         this.altN = n;      
         return this.altCoeff;  
        default:
          return new HFloat();
      }
    }

    protected int    werBinIchP;
    protected int    altN;
    protected HFloat altCoeff;
    
  }  

//Constructors

  public HFloat(){HFloatInit(0, 0, false);}
  
  public HFloat(HFloat orig){HFloatInit(orig.mant, orig.expo, orig.valid);}

  public HFloat(int wertA){HFloatInit(wertA, 0, true);}

  public HFloat(int wertA, int expoA){HFloatInit(wertA, expoA, true);}

  public HFloat(String text){
    if(text.toLowerCase().equals("nan")){
      HFloatInit(0, 0, false);      
    }else{
      int[] hilf = format(text);
      HFloatInit(hilf[0], hilf[1], true);
    }
  }
  
//Cast

  public Integer toInteger(){
    if(!this.valid) return null;
    int     retval = this.mant;
    boolean rund   = false;
    for(int n = 0; n < this.expo; n++) retval *= 10;
    for(int n = 0; n > this.expo; n--){
      if(retval % 10 != 0) rund = true;
      retval /= 10;
    }
    if((this.mant < 0) && rund) retval--;
    return new Integer(retval);
  }

  public String toString(){
    if(!this.valid) return "NaN";
    int expoA;
    int cmpI = cmp().intValue();
    String wertS;
    if(cmpI == -1) return "-" + neg().toString();
    if(cmpI ==  0) expoA = 0;
    else{
       expoA = -1;
       for(int wertA = abs(this.mant); wertA > 0; wertA /= 10) expoA++;
    }
    wertS = (new Integer(this.mant)).toString();
    for(int n = wertS.length(); n < eInt; n++) wertS += "0";
    return wertS.substring(0, 1) + "." + wertS.substring(1, eInt) + "E" + (new Integer(expoA + this.expo)).toString();
  }
  
//  Member (public)

  public HFloat get(){return new HFloat(this);}

  public void set(HFloat orig){HFloatInit(orig.mant, orig.expo, orig.valid);}

  public HFloat add(HFloat arg){
    if(!this.valid || !arg.valid)      return NaN;
    if(    cmp().intValue() == 0) return arg.get();
    if(arg.cmp().intValue() == 0) return get();
    int wertH    = this.mant;
    int argWertH = arg.mant;
    int expoH    = this.expo;
    int argExpoH = arg.expo;
    while(expoH < argExpoH){
      expoH++;
      wertH /= 10;
    }
    while(expoH > argExpoH){
      argExpoH++;
      argWertH /= 10;
    }
    int expoR = expoH;
    int wertR = wertH + argWertH;
    while(wertR > iMax){
      expoR++;
      wertR /= 10;
    }
    return new HFloat(wertR, expoR);
  }
  
  public HFloat add(int    arg){return add(new HFloat(arg));}
  public HFloat add(String arg){return add(new HFloat(arg));}

  public HFloat neg(){
    if(!this.valid) return NaN;
    return new HFloat(-this.mant, this.expo);
  }
  
  public HFloat sbt(HFloat arg){return add(arg.neg());}

  public HFloat sbt(int    arg){return sbt(new HFloat(arg));}
  public HFloat sbt(String arg){return sbt(new HFloat(arg));}

  public HFloat mlt(HFloat arg){
    if(!this.valid || !arg.valid) return NaN;
    int[] hilf  = format(this.mant * (long) arg.mant);
    return new HFloat(hilf[0], this.expo + arg.expo + hilf[1]);
  }
  
  public HFloat mlt(int    arg){return mlt(new HFloat(arg));}
  public HFloat mlt(String arg){return mlt(new HFloat(arg));}

  public HFloat inv(){
    if(!this.valid || (cmp().intValue() == 0)) return NaN;
    int[] hilf  = format(lMax / this.mant);
    return new HFloat(hilf[0], -this.expo - eLong + hilf[1]);
  }
    
  public HFloat div(HFloat arg){return mlt(arg.inv());}
  
  public HFloat div(int    arg){return div(new HFloat(arg));}
  public HFloat div(String arg){return div(new HFloat(arg));}

  public HFloat abs(){
    if(!this.valid)   return NaN;
    if(this.mant < 0) return new HFloat(-this.mant, this.expo);
    else              return new HFloat( this.mant, this.expo);
  }
  
  public Integer cmp(){
    if(!this.valid)         return null;
    if     (this.mant == 0) return new Integer( 0);
    else if(this.mant  > 0) return new Integer( 1);
    else                    return new Integer(-1);
  }
  
  public Integer cmp(HFloat arg){return sbt(arg).cmp();}
  public Integer cmp(int    arg){return sbt(arg).cmp();}
  public Integer cmp(String arg){return sbt(arg).cmp();}
  
  public Integer softCmp(HFloat tol, boolean strict){
    if(!this.valid || !tol.valid) return null;
    int cmpVal = abs().cmp(tol).intValue();
    if((cmpVal == -1) || (!strict && (cmpVal != 1))) return new Integer(0);
    return cmp();
  }
  
  public Integer softCmp(int    tol, boolean strict){return softCmp(new HFloat(tol), strict);}
  public Integer softCmp(String tol, boolean strict){return softCmp(new HFloat(tol), strict);}
  
  
  public Integer softCmp(HFloat arg, HFloat tol, boolean strict){return sbt(arg).softCmp(tol, strict);}
  public Integer softCmp(HFloat arg, int    tol, boolean strict){return sbt(arg).softCmp(tol, strict);}
  public Integer softCmp(HFloat arg, String tol, boolean strict){return sbt(arg).softCmp(tol, strict);}
  public Integer softCmp(int    arg, HFloat tol, boolean strict){return sbt(arg).softCmp(tol, strict);}
  public Integer softCmp(int    arg, int    tol, boolean strict){return sbt(arg).softCmp(tol, strict);}
  public Integer softCmp(int    arg, String tol, boolean strict){return sbt(arg).softCmp(tol, strict);}
  public Integer softCmp(String arg, HFloat tol, boolean strict){return sbt(arg).softCmp(tol, strict);}
  public Integer softCmp(String arg, int    tol, boolean strict){return sbt(arg).softCmp(tol, strict);}
  public Integer softCmp(String arg, String tol, boolean strict){return sbt(arg).softCmp(tol, strict);}
  
  public HFloat unFrac(){
    Integer i = toInteger();
    if(i == null) return NaN;
    return new HFloat(i.intValue());
  }

  public HFloat frac(){return sbt(unFrac());}

  public HFloat mod(HFloat arg){return div(arg).frac().mlt(arg);}
  public HFloat mod(int    arg){return div(arg).frac().mlt(arg);}
  public HFloat mod(String arg){return div(arg).frac().mlt(arg);}
  
  //Analysis
  
  public HFloat quad(){return mlt(this);}  
  
  public HFloat sqrt(){
    if(!this.valid) return NaN;
    int cmpInt = cmp().intValue();
    if(cmpInt == -1) return neg().sqrt();
    if(cmpInt ==  0) return new HFloat(0);
    HFloat altRet = new HFloat(2);
    HFloat ret    = new HFloat(1);
    HFloat arg    = get();
    int    mltMe  = 0;
    while(arg.cmp(1).intValue() == 1){
      ++mltMe;
      arg = arg.div(4);
    }
    for(;ret.cmp(altRet).intValue() == -1;){
    	altRet = ret;
    	ret    = (arg.add(ret.quad())).div(ret).div(2);
    }
    for(int mltLauf = 0; mltLauf < mltMe; ++mltLauf) ret = ret.mlt(2);
    return ret;
  }  
  
  public HFloat pow(HFloat arg){
    if(!this.valid) return NaN;
    if(cmp().intValue() == 0) return new HFloat(0);
    return ln().mlt(arg).exp();
  }
  
  public HFloat pow(int    arg){return pow(new HFloat(arg));}
  public HFloat pow(String arg){return pow(new HFloat(arg));}
  
  public HFloat exp(){
    if(!this.valid)               return NaN;
    if(cmp().intValue() < 0) return neg().exp().inv();  
    return taylor(new HFloatHTaylor(EXP_HTAYLOR));
    
  }
  
  public HFloat ln(){
    if(!this.valid) return NaN;
    int cmpInt = cmp().intValue();
    if(cmpInt ==  0) return NaN;
    if(cmpInt == -1) return neg().ln();
    HFloat arg     = this;
    HFloat zuKlein = new HFloat("0.5");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -