DoublePrecisionNumber.java

/**
 * 
 */
package org.mklab.cga.number;


/**
 * 倍精度の浮動小数点数を表すクラスです。
 * 
 * @author yano
 */
public class DoublePrecisionNumber implements FloatingPointNumber {

  /** 倍精度浮動少数点数で表す値 */
  private double value;

  /**
   * 新しく生成された<code>DoublePrecisionNumber</code>オブジェクトを初期化します。
   * @param value 倍精度浮動少数点数で表す値
   */
  public DoublePrecisionNumber(double value) {
    this.value = value;
  }

  /**
   * {@inheritDoc}
   */
  public String getS() {
    return getBitImage(this.value).substring(0, 1);
  }

  /**
   * double型の値をビット列で表示した文字列に変換します。
   * 
   * @param argValue 変換元の値
   * @return ビット列に変換された文字列
   */
  @SuppressWarnings("boxing")
  private String getBitImage(double argValue) {
    final Long longValue = Double.doubleToRawLongBits(argValue);
    String lb = Long.toBinaryString(longValue);

    final int longBitLength = lb.length();
    for (int i = 64; i > longBitLength; i--) {
      lb = "0" + lb; //$NON-NLS-1$
    }
    return lb;
  }

  /**
   * {@inheritDoc}
   */
  public String getE() {
    return getBitImage(this.value).substring(1, 12);
  }

  /**
   * {@inheritDoc}
   */
  public String getM() {
    return getBitImage(this.value).substring(12);
  }

  /**
   * {@inheritDoc}
   */
  public String getBits() {
    // TODO staticなのもあった方が良い?
    return getBitImage(this.value);
  }

  /**
   * 2つの浮動小数点数間の浮動小数点数の個数を返します。
   * 
   * @param value1 区間の左端
   * @param value2 区間の右端
   * @return 2つの浮動小数点数間の浮動小数点数の個数
   */
  public static long getPointsNumber(double value1, double value2) {
    double now = value1;
    long count = 1;
    while (now < value2) {
      count++;
      now = Math.nextUp(now);
    }
    return count;
  }

  /**
   * 2つの浮動小数点数間の区間からcount番目の浮動小数点数を返します。
   * 
   * @param infimum 区間の左端
   * @param supremum 区間の右端
   * @param count 浮動小数点数の番号
   * @return 2つの浮動小数点数間の区間からcount番目の浮動小数点数
   */
  // TODO supremumいるの?
  public static double getPoint(double infimum, double supremum, long count) {
    double nowValue = infimum;
    long i = 1;

    while (i < count) {
      nowValue = Math.nextUp(nowValue);
      i++;
    }

    return nowValue;
  }

  /**
   * 値が区間内で何番目の浮動小数点かを返します。
   * 
   * @param infimum 区間の下限
   * @param supremum 区間の上限
   * @param value 区間内の値
   * @return valueの区間内での浮動小数点の番号
   */
  // TODO supremumいるの?
  public static long getPointOfValue(double infimum, double supremum, double value) {
    // TODO valueが区間内の値かチェック
    
    double localInfimum = infimum;
    long count = 1;
    while (localInfimum != value) {
      localInfimum = Math.nextUp(localInfimum);
      count++;
    }
    return count;
  }
}