You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gnosygnu_xowa/100_core/src/gplx/Decimal_adp.java

93 lines
5.5 KiB

/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.text.DecimalFormat;
public class Decimal_adp implements CompareAble {
public int compareTo(Object obj) {Decimal_adp comp = (Decimal_adp)obj; return under.compareTo(comp.under);}
protected Decimal_adp(BigDecimal v) {this.under = v;} private final BigDecimal under;
protected Decimal_adp(int v) {this.under = new BigDecimal(v);}
public Object Under() {return under;}
public BigDecimal Under_as_native() {return under;}
public int Precision() {return under.precision();}
public int Frac_1000() {return (int)(under.movePointRight(3).floatValue() % 1000);}
public boolean Eq(Decimal_adp v) {return v.under.doubleValue() == under.doubleValue();}
public boolean Eq(int v) {return under.doubleValue() == v;}
public String To_str() {
BigDecimal tmp = under;
int tmp_scale = tmp.scale();
if (tmp_scale <= -14) return tmp.toString(); // NOTE: if large number, call .toString which will return exponential notaion (1E##) instead of literal (1000....); 14 matches MW code; DATE:2015-04-10
if (tmp_scale > 14)
tmp = tmp.setScale(14, RoundingMode.DOWN); // NOTE: if small number, round down to remove excessive zeroes; 14 matches PHP/C# values more closely; RoundingMode.Down for same reason; see E, Pi tests
return tmp .stripTrailingZeros() // NOTE: stripTrailingZeros for exp tests; EX: 120.0 -> 120; 0.01200000000000 -> .012
.toPlainString(); // NOTE: toPlainString b/c stripTrailingZeros now converts 120 to 1.2E+2 (and any other value that is a multiple of 10)
}
public String To_str(String fmt) {
return new DecimalFormat(fmt).format(under);
}
@Override public String toString() {return under.toString();}
public int To_int() {return (int)under.doubleValue();}
public long To_long() {return (long)under.doubleValue();}
public long To_long_mult_1000() {return under.movePointRight(3).longValue();}
public double To_double() {return under.doubleValue();}
public Decimal_adp Add(Decimal_adp v) {return new Decimal_adp(under.add(v.under, Decimal_adp_.Gplx_rounding_context));}
public Decimal_adp Subtract(Decimal_adp v) {return new Decimal_adp(under.subtract(v.under, Decimal_adp_.Gplx_rounding_context));}
public Decimal_adp Multiply(Decimal_adp v) {return new Decimal_adp(under.multiply(v.under));}
public Decimal_adp Multiply(double v) {return new Decimal_adp(under.multiply(new BigDecimal(v, Decimal_adp_.Gplx_rounding_context)));}
public Decimal_adp Multiply(long v) {return new Decimal_adp(under.multiply(new BigDecimal(v)));}
public Decimal_adp Divide(Decimal_adp v) {return new Decimal_adp(under.divide(v.under, Decimal_adp_.Gplx_rounding_context));}
public Decimal_adp Mod(Decimal_adp v) {return new Decimal_adp(under.remainder(v.under, Decimal_adp_.Gplx_rounding_context));}
public Decimal_adp Abs() {return new Decimal_adp(under.abs(Decimal_adp_.Gplx_rounding_context));}
public Decimal_adp Pow(int v) {return new Decimal_adp(under.pow(v, Decimal_adp_.Gplx_rounding_context));}
public Decimal_adp Sqrt() {return new Decimal_adp(new BigDecimal(Math_.Sqrt(under.doubleValue())));}
public Decimal_adp Truncate() {return new Decimal_adp(under.intValue());}
public Decimal_adp Round_old(int v) {return new Decimal_adp(under.setScale(v, RoundingMode.HALF_UP));}
public Decimal_adp Round(int v) {
BigDecimal new_val = null;
if (v > 0) {
new_val = under.setScale(v, RoundingMode.HALF_UP);
}
else {
int actl_places = under.precision() - under.scale();
int reqd_places = -v;
if (reqd_places < actl_places)
new_val = under.round(new java.math.MathContext(actl_places - reqd_places, RoundingMode.HALF_UP));
else if (reqd_places == actl_places) {
int base_10 = (int)Math_.Pow(10, reqd_places - 1);
if (under.intValue() / base_10 < 5)
new_val = BigDecimal.ZERO;
else
new_val = new BigDecimal(Math_.Pow(10, reqd_places));
}
else
new_val = BigDecimal.ZERO;
}
return new Decimal_adp(new_val);
}
public boolean Comp_gte(Decimal_adp v) {return under.doubleValue() >= v.under.doubleValue();}
public boolean Comp_gte(int v) {return under.doubleValue() >= v;}
public boolean Comp_lte(Decimal_adp v) {return under.doubleValue() <= v.under.doubleValue();}
public boolean Comp_lte(int v) {return under.doubleValue() <= v;}
public boolean Comp_gt(Decimal_adp v) {return under.doubleValue() > v.under.doubleValue();}
public boolean Comp_gt(int v) {return under.doubleValue() > v;}
public boolean Comp_lt(Decimal_adp v) {return under.doubleValue() < v.under.doubleValue();}
public boolean Comp_lt(int v) {return under.doubleValue() < v;}
}