All Downloads are FREE. Search and download functionalities are using the official Maven repository.

weka.core.matrix.FlexibleDecimalFormat Maven / Gradle / Ivy

Go to download

The Waikato Environment for Knowledge Analysis (WEKA), a machine learning workbench. This is the stable version. Apart from bugfixes, this version does not receive any other updates.

There is a newer version: 3.8.6
Show newest version
/*
 *   This program 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 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program 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 should have received a copy of the GNU General Public License
 *   along with this program.  If not, see .
 */

/*
 *    FlexibleDecimalFormat.java
 *    Copyright (C) 2002-2012 University of Waikato, Hamilton, New Zealand
 *
 */

package weka.core.matrix;

import java.text.DecimalFormat;
import java.text.FieldPosition;

import weka.core.RevisionHandler;
import weka.core.RevisionUtils;

/**
 * @author Yong Wang
 * @version $Revision: 10835 $
 */
public class FlexibleDecimalFormat extends DecimalFormat implements
  RevisionHandler {

  /** for serialization */
  private static final long serialVersionUID = 110912192794064140L;

  private DecimalFormat nf = null;
  private int digits = 7;
  private boolean exp = false;
  private int intDigits = 1;
  private int decimalDigits = 0;
  private int expDecimalDigits = 0; // ???
  private int power = 2;
  private boolean trailing = false;
  private boolean grouping = false;
  private boolean sign = false;

  public FlexibleDecimalFormat() {
    this(5);
  }

  public FlexibleDecimalFormat(int digits) {
    if (digits < 1) {
      throw new IllegalArgumentException("digits < 1");
    }
    this.digits = digits;
    intDigits = 1;
  }

  public FlexibleDecimalFormat(int digits, boolean trailing) {
    this(digits);
    this.trailing = trailing;
  }

  public FlexibleDecimalFormat(int digits, boolean exp, boolean trailing,
    boolean grouping) {
    this.trailing = trailing;
    this.exp = exp;
    this.digits = digits;
    this.grouping = grouping;
    if (exp) {
      this.intDigits = 1;
      this.decimalDigits = digits - intDigits;
    } else {
      this.intDigits = Math.max(1, digits - decimalDigits);
    }
  }

  public FlexibleDecimalFormat(double d) {
    newFormat(d);
  }

  private void newFormat(double d) {
    if (needExponentialFormat(d)) {
      exp = true;
      intDigits = 1;
      expDecimalDigits = decimalDigits(d, true);
      if (d < 0) {
        sign = true;
      } else {
        sign = false;
      }
    } else {
      exp = false;
      intDigits = Math.max(1, intDigits(d));
      decimalDigits = decimalDigits(d, false);
      if (d < 0.0) {
        sign = true;
      } else {
        sign = false;
      }
    }
  }

  public void update(double d) {
    if (Math.abs(intDigits(d) - 1) > 99) {
      power = 3;
    }
    expDecimalDigits = Math.max(expDecimalDigits, decimalDigits(d, true));
    if (d < 0) {
      sign = true;
    }
    if (needExponentialFormat(d) || exp) {
      exp = true;
    } else {
      intDigits = Math.max(intDigits, intDigits(d));
      decimalDigits = Math.max(decimalDigits, decimalDigits(d, false));
      if (d < 0) {
        sign = true;
      }
    }
  }

  private static int intDigits(double d) {
    return (int) Math.floor(Math.log(Math.abs(d * (1 + 1e-14))) / Math.log(10)) + 1;
  }

  private int decimalDigits(double d, boolean expo) {
    if (d == 0.0) {
      return 0;
    }
    d = Math.abs(d);
    int e = intDigits(d);
    if (expo) {
      d /= Math.pow(10, e - 1);
      e = 1;
    }
    if (e >= digits) {
      return 0;
    }
    int iD = Math.max(1, e);
    int dD = digits - e;
    if (!trailing && dD > 0) { // to get rid of trailing zeros
      FloatingPointFormat f = new FloatingPointFormat(iD + 1 + dD, dD, true);
      String dString = f.nf.format(d);
      while (dD > 0) {
        if (dString.charAt(iD + 1 + dD - 1) == '0') {
          dD--;
        } else {
          break;
        }
      }
    }
    return dD;
  }

  public boolean needExponentialFormat(double d) {
    if (d == 0.0) {
      return false;
    }
    int e = intDigits(d);
    if (e > digits + 5 || e < -3) {
      return true;
    } else {
      return false;
    }
  }

  public void grouping(boolean grouping) {
    this.grouping = grouping;
  }

  private void setFormat() {
    int dot = 1;
    if (decimalDigits == 0) {
      dot = 0;
    }
    if (exp) {
      nf = new ExponentialFormat(1 + expDecimalDigits, power, sign, grouping
        || trailing);
    } else {
      int s = sign ? 1 : 0;
      nf = new FloatingPointFormat(s + intDigits + dot + decimalDigits,
        decimalDigits, grouping || trailing);
    }
  }

  private void setFormat(double d) {
    newFormat(d);
    setFormat();
  }

  @Override
  public StringBuffer format(double number, StringBuffer toAppendTo,
    FieldPosition pos) {
    if (grouping) {
      if (nf == null) {
        setFormat();
      }
    } else {
      setFormat(number);
    }

    return toAppendTo.append(nf.format(number));
  }

  public int width() {

    if (!trailing && !grouping) {
      throw new RuntimeException("flexible width");
    }

    return format(0.).length();
  }

  public StringBuffer formatString(String str) {
    int w = width();
    int h = (w - str.length()) / 2;
    StringBuffer text = new StringBuffer();
    for (int i = 0; i < h; i++) {
      text.append(' ');
    }
    text.append(str);
    for (int i = 0; i < w - h - str.length(); i++) {
      text.append(' ');
    }
    return text;
  }

  /**
   * Returns the revision string.
   * 
   * @return the revision
   */
  @Override
  public String getRevision() {
    return RevisionUtils.extract("$Revision: 10835 $");
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy