Core: Parse decimal 'e' as 'E' [#565]

staging v4.6.10.2008
gnosygnu 4 years ago
parent 1eea3682ca
commit 6ed7659b4d

@ -1,6 +1,6 @@
/* /*
XOWA: the XOWA Offline Wiki Application XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3, XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0. or alternatively under the terms of the Apache License Version 2.0.
@ -13,57 +13,75 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx; package gplx;
import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; import java.text.DecimalFormat;
import java.text.NumberFormat; import java.math.BigDecimal;
import java.text.ParseException; import java.math.MathContext;
import java.util.Locale; import java.math.RoundingMode;
public class Decimal_adp_ { import java.text.DecimalFormat;
public static final String Cls_val_name = "decimal"; import java.text.NumberFormat;
public static final Class<?> Cls_ref_type = Decimal_adp.class; import java.text.ParseException;
public static Decimal_adp as_(Object obj) {return obj instanceof Decimal_adp ? (Decimal_adp)obj : null;} import java.util.Locale;
public static final Decimal_adp Zero = new Decimal_adp(0);
public static final Decimal_adp One = new Decimal_adp(1); public class Decimal_adp_ {
public static final Decimal_adp Neg1 = new Decimal_adp(-1); public static final String Cls_val_name = "decimal";
public static final Decimal_adp Const_e = Decimal_adp_.double_(Math_.E); public static final Class<?> Cls_ref_type = Decimal_adp.class;
public static final Decimal_adp Const_pi = Decimal_adp_.double_(Math_.Pi); public static Decimal_adp as_(Object obj) {return obj instanceof Decimal_adp ? (Decimal_adp)obj : null;}
public static Decimal_adp base1000_(long v) {return divide_(v, 1000);} public static final Decimal_adp Zero = new Decimal_adp(0);
public static Decimal_adp parts_1000_(long num, int frc) {return divide_((num * (1000)) + frc, 1000);} public static final Decimal_adp One = new Decimal_adp(1);
public static Decimal_adp parts_(long num, int frc) { public static final Decimal_adp Neg1 = new Decimal_adp(-1);
// int log10 = frc == 0 ? 0 : (Math_.Log10(frc) + 1); public static final Decimal_adp Const_e = Decimal_adp_.double_(Math_.E);
// int pow10 = (int)Math_.Pow(10, log10); public static final Decimal_adp Const_pi = Decimal_adp_.double_(Math_.Pi);
int pow10 = XtoPow10(frc); public static Decimal_adp base1000_(long v) {return divide_(v, 1000);}
return divide_((num * (pow10)) + frc, pow10); public static Decimal_adp parts_1000_(long num, int frc) {return divide_((num * (1000)) + frc, 1000);}
} public static Decimal_adp parts_(long num, int frc) {
public static Decimal_adp cast(Object obj) {return (Decimal_adp)obj;} // int log10 = frc == 0 ? 0 : (Math_.Log10(frc) + 1);
static int XtoPow10(int v) { // int pow10 = (int)Math_.Pow(10, log10);
if (v > -1 && v < 10) return 10; int pow10 = XtoPow10(frc);
else if (v > 9 && v < 100) return 100; return divide_((num * (pow10)) + frc, pow10);
else if (v > 99 && v < 1000) return 1000; }
else if (v > 999 && v < 10000) return 10000; public static Decimal_adp cast(Object obj) {return (Decimal_adp)obj;}
else if (v > 9999 && v < 100000) return 100000; static int XtoPow10(int v) {
else if (v > 99999 && v < 1000000) return 1000000; if (v > -1 && v < 10) return 10;
else if (v > 999999 && v < 10000000) return 10000000; else if (v > 9 && v < 100) return 100;
else if (v > 9999999 && v < 100000000) return 100000000; else if (v > 99 && v < 1000) return 1000;
else if (v > 99999999 && v < 1000000000) return 1000000000; else if (v > 999 && v < 10000) return 10000;
else throw Err_.new_wo_type("value must be between 0 and 1 billion", "v", v); else if (v > 9999 && v < 100000) return 100000;
} else if (v > 99999 && v < 1000000) return 1000000;
public static String CalcPctStr(long dividend, long divisor, String fmt) { else if (v > 999999 && v < 10000000) return 10000000;
if (divisor == 0) return "%ERR"; else if (v > 9999999 && v < 100000000) return 100000000;
return Decimal_adp_.float_(Float_.Div(dividend, divisor) * 100).To_str(fmt) + "%"; else if (v > 99999999 && v < 1000000000) return 1000000000;
} else throw Err_.new_wo_type("value must be between 0 and 1 billion", "v", v);
public static Decimal_adp divide_safe_(long lhs, long rhs) {return rhs == 0 ? Zero : divide_(lhs, rhs);} }
public static Decimal_adp divide_(long lhs, long rhs) { return new Decimal_adp(new BigDecimal(lhs).divide(new BigDecimal(rhs), Gplx_rounding_context)); } public static Decimal_adp int_(int v) {return new Decimal_adp(new BigDecimal(v));} public static Decimal_adp long_(long v) {return new Decimal_adp(new BigDecimal(v));} public static String CalcPctStr(long dividend, long divisor, String fmt) {
public static Decimal_adp float_(float v) {return new Decimal_adp(new BigDecimal(v));} public static Decimal_adp double_(double v) {return new Decimal_adp(new BigDecimal(v));} if (divisor == 0) return "%ERR";
public static Decimal_adp double_thru_str_(double v) {return new Decimal_adp(BigDecimal.valueOf(v));} return Decimal_adp_.float_(Float_.Div(dividend, divisor) * 100).To_str(fmt) + "%";
public static Decimal_adp db_(Object v) {return new Decimal_adp((BigDecimal)v);} public static Decimal_adp parse(String raw) { }
try { public static Decimal_adp divide_safe_(long lhs, long rhs) {return rhs == 0 ? Zero : divide_(lhs, rhs);}
DecimalFormat nf = (DecimalFormat)NumberFormat.getInstance(Locale.US); // always parse as US format; EX:".9" should not be ",9" in german; DATE:2016-01-31 public static Decimal_adp divide_(long lhs, long rhs) {
nf.setParseBigDecimal(true); return new Decimal_adp(new BigDecimal(lhs).divide(new BigDecimal(rhs), Gplx_rounding_context));
BigDecimal bd = (BigDecimal)nf.parse(raw); }
return new Decimal_adp(bd); public static Decimal_adp int_(int v) {return new Decimal_adp(new BigDecimal(v));}
} catch (ParseException e) { public static Decimal_adp long_(long v) {return new Decimal_adp(new BigDecimal(v));}
throw Err_.new_("Decimal_adp_", "parse to decimal failed", "raw", raw); public static Decimal_adp float_(float v) {return new Decimal_adp(new BigDecimal(v));}
} public static Decimal_adp double_(double v) {return new Decimal_adp(new BigDecimal(v));}
} public static Decimal_adp pow_10_(int v) {return new Decimal_adp(new BigDecimal(1).scaleByPowerOfTen(v));} public static Decimal_adp double_thru_str_(double v) {return new Decimal_adp(BigDecimal.valueOf(v));}
public static final MathContext RoundDownContext = new MathContext(0, RoundingMode.DOWN); public static final MathContext Gplx_rounding_context = new MathContext(14, RoundingMode.HALF_UP); // changed from 28 to 14; DATE:2015-07-31 } public static Decimal_adp db_(Object v) {return new Decimal_adp((BigDecimal)v);}
public static Decimal_adp parse(String raw) {
try {
DecimalFormat nf = (DecimalFormat)NumberFormat.getInstance(Locale.US); // always parse as US format; EX:".9" should not be ",9" in german; DATE:2016-01-31
nf.setParseBigDecimal(true);
// 2020-08-27|ISSUE#:565|Parse 'e' as 'E'; PAGE:en.w:Huntington_Plaza
if (raw.contains("e")) {
raw = raw.replace("e", "E");
}
BigDecimal bd = (BigDecimal)nf.parse(raw);
return new Decimal_adp(bd);
} catch (ParseException e) {
throw Err_.new_("Decimal_adp_", "parse to decimal failed", "raw", raw);
}
}
public static Decimal_adp pow_10_(int v) {return new Decimal_adp(new BigDecimal(1).scaleByPowerOfTen(v));}
public static final MathContext RoundDownContext = new MathContext(0, RoundingMode.DOWN);
public static final MathContext Gplx_rounding_context = new MathContext(14, RoundingMode.HALF_UP); // changed from 28 to 14; DATE:2015-07-31
}

@ -1,6 +1,6 @@
/* /*
XOWA: the XOWA Offline Wiki Application XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com Copyright (C) 2012-2020 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3, XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0. or alternatively under the terms of the Apache License Version 2.0.
@ -13,75 +13,78 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/ */
package gplx; package gplx;
import org.junit.*;
public class Decimal_adp__tst { import org.junit.*;
private final Decimal_adp__fxt fxt = new Decimal_adp__fxt();
@Test public void divide_() { public class Decimal_adp__tst {
fxt.Test_divide(1, 1000, "0.001"); private final Decimal_adp__fxt fxt = new Decimal_adp__fxt();
fxt.Test_divide(1, 3, "0.33333333333333"); @Test public void divide_() {
fxt.Test_divide(1, 7, "0.14285714285714"); fxt.Test_divide(1, 1000, "0.001");
} fxt.Test_divide(1, 3, "0.33333333333333");
@Test public void base1000_() { fxt.Test_divide(1, 7, "0.14285714285714");
fxt.Test_base_1000(1000, "1"); }
fxt.Test_base_1000(1234, "1.234"); @Test public void base1000_() {
fxt.Test_base_1000(123, "0.123"); fxt.Test_base_1000(1000, "1");
} fxt.Test_base_1000(1234, "1.234");
@Test public void parts_() { fxt.Test_base_1000(123, "0.123");
fxt.Test_parts(1, 0, "1"); }
fxt.Test_parts(1, 2, "1.2"); @Test public void parts_() {
fxt.Test_parts(1, 23, "1.23"); fxt.Test_parts(1, 0, "1");
fxt.Test_parts(123, 4567, "123.4567"); fxt.Test_parts(1, 2, "1.2");
} fxt.Test_parts(1, 23, "1.23");
@Test public void parse() { fxt.Test_parts(123, 4567, "123.4567");
fxt.Test_parse("1", "1"); }
fxt.Test_parse("1.2", "1.2"); @Test public void parse() {
fxt.Test_parse("0.1", "0.1"); fxt.Test_parse("1", "1");
fxt.Test_parse("1.2E1", "12"); fxt.Test_parse("1.2", "1.2");
} fxt.Test_parse("0.1", "0.1");
@Test public void Truncate_decimal() { fxt.Test_parse("1.2E1", "12");
fxt.Test_truncate_decimal("1", "1"); fxt.Test_parse("1.2e1", "12"); // 2020-08-27|ISSUE#:565|Parse 'e' as 'E'; PAGE:en.w:Huntington_Plaza
fxt.Test_truncate_decimal("1.1", "1"); }
fxt.Test_truncate_decimal("1.9", "1"); @Test public void Truncate_decimal() {
} fxt.Test_truncate_decimal("1", "1");
@Test public void Fraction1000() { fxt.Test_truncate_decimal("1.1", "1");
fxt.Test_frac_1000(1, 1000, 1); // 0.001 fxt.Test_truncate_decimal("1.9", "1");
fxt.Test_frac_1000(1, 3, 333); // 0.33333333 }
fxt.Test_frac_1000(1234, 1000, 234); // 1.234 @Test public void Fraction1000() {
fxt.Test_frac_1000(12345, 10000, 234); // 1.2345 fxt.Test_frac_1000(1, 1000, 1); // 0.001
} fxt.Test_frac_1000(1, 3, 333); // 0.33333333
@Test public void Lt() { fxt.Test_frac_1000(1234, 1000, 234); // 1.234
fxt.Test_comp_lt(1,123, 2, true); fxt.Test_frac_1000(12345, 10000, 234); // 1.2345
fxt.Test_comp_lt(1,99999999, 2, true); }
} @Test public void Lt() {
@Test public void To_str_fmt() { fxt.Test_comp_lt(1,123, 2, true);
fxt.Test_to_str_fmt(1, 2, "0.0", "0.5"); fxt.Test_comp_lt(1,99999999, 2, true);
fxt.Test_to_str_fmt(1, 3, "0.0", "0.3"); }
fxt.Test_to_str_fmt(10000, 7, "0,000.000", "1,428.571"); @Test public void To_str_fmt() {
fxt.Test_to_str_fmt(1, 2, "00.00", "00.50"); fxt.Test_to_str_fmt(1, 2, "0.0", "0.5");
} fxt.Test_to_str_fmt(1, 3, "0.0", "0.3");
@Test public void Round() { fxt.Test_to_str_fmt(10000, 7, "0,000.000", "1,428.571");
fxt.Test_round("123.456", 3, "123.456"); fxt.Test_to_str_fmt(1, 2, "00.00", "00.50");
fxt.Test_round("123.456", 2, "123.46"); }
fxt.Test_round("123.456", 1, "123.5"); @Test public void Round() {
fxt.Test_round("123.456", 0, "123"); fxt.Test_round("123.456", 3, "123.456");
fxt.Test_round("123.456", -1, "120"); fxt.Test_round("123.456", 2, "123.46");
fxt.Test_round("123.456", -2, "100"); fxt.Test_round("123.456", 1, "123.5");
fxt.Test_round("123.456", -3, "0"); fxt.Test_round("123.456", 0, "123");
fxt.Test_round("123.456", -1, "120");
fxt.Test_round("6", -1, "10"); fxt.Test_round("123.456", -2, "100");
fxt.Test_round("5", -1, "10"); fxt.Test_round("123.456", -3, "0");
fxt.Test_round("6", -2, "0");
} fxt.Test_round("6", -1, "10");
} fxt.Test_round("5", -1, "10");
class Decimal_adp__fxt { fxt.Test_round("6", -2, "0");
public void Test_divide(int lhs, int rhs, String expd) {Tfds.Eq(expd, Decimal_adp_.divide_(lhs, rhs).To_str());} }
public void Test_base_1000(int val, String expd) {Tfds.Eq(expd, Decimal_adp_.base1000_(val).To_str());} }
public void Test_parts(int num, int fracs, String expd) {Tfds.Eq(expd, Decimal_adp_.parts_(num, fracs).To_str());} class Decimal_adp__fxt {
public void Test_parse(String raw, String expd) {Tfds.Eq(expd, Decimal_adp_.parse(raw).To_str());} public void Test_divide(int lhs, int rhs, String expd) {Tfds.Eq(expd, Decimal_adp_.divide_(lhs, rhs).To_str());}
public void Test_truncate_decimal(String raw, String expd) {Tfds.Eq(Decimal_adp_.parse(expd).To_str(), Decimal_adp_.parse(raw).Truncate().To_str());} public void Test_base_1000(int val, String expd) {Tfds.Eq(expd, Decimal_adp_.base1000_(val).To_str());}
public void Test_frac_1000(int lhs, int rhs, int expd) {Tfds.Eq(expd, Decimal_adp_.divide_(lhs, rhs).Frac_1000());} public void Test_parts(int num, int fracs, String expd) {Tfds.Eq(expd, Decimal_adp_.parts_(num, fracs).To_str());}
public void Test_comp_lt(int lhsNum, int lhsFrc, int rhs, boolean expd) {Tfds.Eq(expd, Decimal_adp_.parts_(lhsNum, lhsFrc).Comp_lt(rhs));} public void Test_parse(String raw, String expd) {Tfds.Eq(expd, Decimal_adp_.parse(raw).To_str());}
public void Test_to_str_fmt(int l, int r, String fmt, String expd) {Tfds.Eq(expd, Decimal_adp_.divide_(l, r).To_str(fmt));} public void Test_truncate_decimal(String raw, String expd) {Tfds.Eq(Decimal_adp_.parse(expd).To_str(), Decimal_adp_.parse(raw).Truncate().To_str());}
public void Test_round(String raw, int places, String expd) {Tfds.Eq_str(expd, Decimal_adp_.parse(raw).Round(places).To_str(), "round");} public void Test_frac_1000(int lhs, int rhs, int expd) {Tfds.Eq(expd, Decimal_adp_.divide_(lhs, rhs).Frac_1000());}
} public void Test_comp_lt(int lhsNum, int lhsFrc, int rhs, boolean expd) {Tfds.Eq(expd, Decimal_adp_.parts_(lhsNum, lhsFrc).Comp_lt(rhs));}
public void Test_to_str_fmt(int l, int r, String fmt, String expd) {Tfds.Eq(expd, Decimal_adp_.divide_(l, r).To_str(fmt));}
public void Test_round(String raw, int places, String expd) {Tfds.Eq_str(expd, Decimal_adp_.parse(raw).Round(places).To_str(), "round");}
}

Loading…
Cancel
Save