com.github.mygreen.cellformatter.number.FractionNumber Maven / Gradle / Ivy
Show all versions of excel-cellformatter Show documentation
package com.github.mygreen.cellformatter.number;
/**
* 分数を表現するクラス。
* POIのSimpleFraction、Commons-MathのFractionを参照。
* @author T.TSUCHIE
*
*/
public class FractionNumber extends FormattedNumber {
/**
* 分母の部分
*/
private String denominatorPart;
/**
* 分子の部分
*/
private String numeratorPart;
/**
* 帯分数の整数部分
*/
private String wholeNumberPart;
/**
* 帯分数の形式かどうか。
*/
private boolean wholeType;
private FractionNumber(final double value) {
super(value);
}
/**
* 分母の値を指定した分数を作成する。その際に、仮分数として作成する。
* @param value
* @param exactDenom 分母の値
* @return
*/
public static FractionNumber createExactDenominator(final double value, int exactDenom) {
return createExactDenominator(value, exactDenom, false);
}
/**
* 分母の値を指定した分数を作成する。
* @param value
* @param exactDenom 分母の値
* @param wholeType 'true'のとき帯分数として作成する。'false'のとき仮分数として作成する。
* @return
*/
public static FractionNumber createExactDenominator(final double value, int exactDenom, boolean wholeType) {
final FractionNumber fractionNumber = new FractionNumber(value);
fractionNumber.wholeType = wholeType;
final SimpleFraction fraction = SimpleFraction.createFractionExactDenominator(Math.abs(value), exactDenom);
setupFractionPart(fraction, fractionNumber);
return fractionNumber;
}
/**
* 分母の最大値を指定した分数を作成する。その際に、仮分数として作成する。
* @param value
* @param maxDenom
* @return
*/
public static FractionNumber createMaxDenominator(final double value, int maxDenom) {
return createMaxDenominator(value, maxDenom, false);
}
/**
* 分母の最大値を指定した分数を作成する。
* @param value
* @param maxDenom 分母の最大値。
* @param wholeType 'true'のとき帯分数として作成する。'false'のとき仮分数として作成する。
* @return
*/
public static FractionNumber createMaxDenominator(final double value, int maxDenom, boolean wholeType) {
final FractionNumber fractionNumber = new FractionNumber(value);
fractionNumber.wholeType = wholeType;
final SimpleFraction fraction = SimpleFraction.createFractionMaxDenominator(Math.abs(value), maxDenom);
setupFractionPart(fraction, fractionNumber);
return fractionNumber;
}
/**
* 分数の各部品を設定する
* @param fraction
* @param fractionNumber
*/
private static void setupFractionPart(final SimpleFraction fraction, final FractionNumber fractionNumber) {
fractionNumber.denominatorPart = String.valueOf(fraction.getDenominator());
if(fractionNumber.isWholeType()) {
int wholeNumber = fraction.getNumerator() / fraction.getDenominator();
fractionNumber.wholeNumberPart = wholeNumber == 0 ? "" : String.valueOf(wholeNumber);
int numerator = fraction.getNumerator() % fraction.getDenominator();
fractionNumber.numeratorPart = String.valueOf(numerator);
} else {
fractionNumber.wholeNumberPart = "";
fractionNumber.numeratorPart = String.valueOf(fraction.getNumerator());
}
}
/**
* 帯分数の形式かどうか。
* @return
*/
public boolean isWholeType() {
return wholeType;
}
/**
* 分母の部分を取得する。
* @return
*/
public String getDenominatorPart() {
return denominatorPart;
}
/**
* 分母の指定した桁の値を取得する。
* @param digit 1から始まる
* @return 存在しない桁の場合は空文字を返す。
*/
public String getDenominatorPart(final int digit) {
final int length = denominatorPart.length();
if(length < digit || digit <= 0) {
return "";
}
return String.valueOf(denominatorPart.charAt(length - digit));
}
/**
* 分母の指定した桁以降の値を取得する。
* @param digit 1から始まる
* @return 存在しない桁の場合は空文字を返す。
*/
public String getDenominatorPartAfter(final int digit) {
final int length = denominatorPart.length();
if(length < digit || digit <= 0) {
return "";
}
return denominatorPart.substring(0, (length - digit + 1));
}
/**
* 分子の部分を取得する
* @return
*/
public String getNumeratorPart() {
return numeratorPart;
}
/**
* 分子の指定した桁の値を取得する。
* @param digit 1から始まる
* @return 存在しない桁の場合は空文字を返す。
*/
public String getNumeratorPart(final int digit) {
final int length = numeratorPart.length();
if(length < digit || digit <= 0) {
return "";
}
return String.valueOf(numeratorPart.charAt(length - digit));
}
/**
* 分子の指定した桁以降の値を取得する。
* @param digit 1から始まる
* @return 存在しない桁の場合は空文字を返す。
*/
public String getNumeratorPartAfter(final int digit) {
final int length = numeratorPart.length();
if(length < digit || digit <= 0) {
return "";
}
return numeratorPart.substring(0, (length - digit + 1));
}
/**
* 帯分数の整数部分を取得する。
*
整数部分が0または帯分数出ない場合は、空文字を返す。
* @return
*/
public String getWholeNumberPart() {
return wholeNumberPart;
}
/**
* 帯分数の整数部分の指定した桁の値を取得する。
* @param digit 1から始まる
* @return 存在しない桁の場合は空文字を返す。
*/
public String getWholeNumberPart(final int digit) {
final int length = wholeNumberPart.length();
if(length < digit || digit <= 0) {
return "";
}
return String.valueOf(wholeNumberPart.charAt(length - digit));
}
/**
* 帯分数の整数部分の指定した桁以降の値を取得する。
* @param digit 1から始まる
* @return 存在しない桁の場合は空文字を返す。
*/
public String getWholeNumberPartAfter(final int digit) {
final int length = wholeNumberPart.length();
if(length < digit || digit <= 0) {
return "";
}
return wholeNumberPart.substring(0, (length - digit + 1));
}
@Override
public String toString() {
if(isZero()) {
return "0";
}
StringBuilder sb = new StringBuilder();
if(isNegative()) {
sb.append("-");
}
if(isWholeType() && !getWholeNumberPart().isEmpty()) {
sb.append(getWholeNumberPart()).append(" ");
}
sb.append(getNumeratorPart()).append("/").append(getDenominatorPart());
return sb.toString();
}
}