mirror of https://github.com/gnosygnu/xowa
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.
221 lines
8.2 KiB
221 lines
8.2 KiB
/*
|
|
XOWA: the XOWA Offline Wiki Application
|
|
Copyright (C) 2012-2017 gnosygnu@gmail.com
|
|
|
|
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.
|
|
|
|
You may use XOWA according to either of these licenses as is most appropriate
|
|
for your project on a case-by-case basis.
|
|
|
|
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
|
|
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
|
*/
|
|
package gplx;
|
|
import gplx.core.strings.*; import gplx.langs.gfs.*;
|
|
public class Int_ {
|
|
public static final String Cls_val_name = "int";
|
|
public static final Class<?> Cls_ref_type = Integer.class;
|
|
|
|
public static final int
|
|
Min_value = Integer.MIN_VALUE
|
|
, Max_value = Integer.MAX_VALUE
|
|
, Max_value__31 = 2147483647
|
|
, Neg1 = -1
|
|
, Null = Int_.Min_value
|
|
, Base1 = 1 // for super 1 lists / arrays; EX: PHP; [a, b, c]; [1] => a
|
|
, Offset_1 = 1 // common symbol for + 1 after current pos; EX: String_.Mid(lhs + Offset_1, rhs)
|
|
;
|
|
|
|
public static int Cast(Object obj) {
|
|
try {
|
|
return (Integer)obj;
|
|
}
|
|
catch(Exception exc) {
|
|
throw Err_.new_type_mismatch_w_exc(exc, int.class, obj);
|
|
}
|
|
}
|
|
public static int Cast_or(Object obj, int or) {
|
|
try {
|
|
return (Integer)obj;
|
|
}
|
|
catch(Exception e) {
|
|
Err_.Noop(e);
|
|
return or;
|
|
}
|
|
}
|
|
public static int Coerce(Object v) {
|
|
try {
|
|
String s = String_.as_(v);
|
|
return s == null ? Int_.Cast(v) : Int_.Parse(s);
|
|
}
|
|
catch (Exception e) {throw Err_.new_cast(e, int.class, v);}
|
|
}
|
|
|
|
public static int Parse(String raw) {try {return Integer.parseInt(raw);} catch(Exception e) {throw Err_.new_parse_exc(e, int.class, raw);}}
|
|
public static int Parse_or(String raw, int or) {
|
|
if (raw == null) return or;
|
|
int rawLen = String_.Len(raw); if (rawLen == 0) return or;
|
|
int rv = 0, tmp = 0, factor = 1;
|
|
for (int i = rawLen; i > 0; i--) {
|
|
char c = String_.CharAt(raw, i - 1);
|
|
switch (c) {
|
|
case '0': tmp = 0; break; case '1': tmp = 1; break; case '2': tmp = 2; break; case '3': tmp = 3; break; case '4': tmp = 4; break;
|
|
case '5': tmp = 5; break; case '6': tmp = 6; break; case '7': tmp = 7; break; case '8': tmp = 8; break; case '9': tmp = 9; break;
|
|
case '-': rv *= -1; continue; // NOTE: note continue
|
|
default: return or;
|
|
}
|
|
rv += (tmp * factor);
|
|
factor *= 10;
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
public static int By_double(double v) {return (int)v;}
|
|
public static int By_hex_bry(byte[] src) {return By_hex_bry(src, 0, src.length);}
|
|
public static int By_hex_bry(byte[] src, int bgn, int end) {
|
|
int rv = 0; int factor = 1;
|
|
for (int i = end - 1; i >= bgn; i--) {
|
|
int val = By_hex_byte(src[i]);
|
|
rv += (val * factor);
|
|
factor *= 16;
|
|
}
|
|
return rv;
|
|
}
|
|
public static int By_hex_byte(byte b) {
|
|
switch (b) {
|
|
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
|
|
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
|
|
return b - Byte_ascii.Num_0;
|
|
case Byte_ascii.Ltr_A: case Byte_ascii.Ltr_B: case Byte_ascii.Ltr_C: case Byte_ascii.Ltr_D: case Byte_ascii.Ltr_E: case Byte_ascii.Ltr_F:
|
|
return b - Byte_ascii.Ltr_A + 10;
|
|
case Byte_ascii.Ltr_a: case Byte_ascii.Ltr_b: case Byte_ascii.Ltr_c: case Byte_ascii.Ltr_d: case Byte_ascii.Ltr_e: case Byte_ascii.Ltr_f:
|
|
return b - Byte_ascii.Ltr_a + 10;
|
|
default:
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
public static byte[] To_bry(int v) {return Bry_.new_a7(To_str(v));}
|
|
public static String To_str(int v) {return new Integer(v).toString();}
|
|
public static String To_str_fmt(int v, String fmt) {return new java.text.DecimalFormat(fmt).format(v);}
|
|
public static String To_str_pad_bgn_space(int val, int reqd_len) {return To_str_pad(val, reqd_len, Bool_.Y, Byte_ascii.Space);} // EX: 1, 3 returns " 1"
|
|
public static String To_str_pad_bgn_zero (int val, int reqd_len) {return To_str_pad(val, reqd_len, Bool_.Y, Byte_ascii.Num_0);} // EX: 1, 3 returns "001"
|
|
private static String To_str_pad(int val, int reqd_len, boolean bgn, byte pad_chr) {
|
|
// get val_len and pad_len; exit early, if no padding needed
|
|
int val_len = DigitCount(val);
|
|
int pad_len = reqd_len - val_len;
|
|
if (pad_len < 0)
|
|
return Int_.To_str(val);
|
|
|
|
// padding needed
|
|
Bry_bfr bfr = Bry_bfr_.New();
|
|
|
|
// handle negative numbers; EX: -1 -> "-001", not "00-1"
|
|
if (val < 0) {
|
|
bfr.Add_byte(Byte_ascii.Dash);
|
|
val *= -1;
|
|
--val_len;
|
|
}
|
|
|
|
// build outpt
|
|
if (!bgn)
|
|
bfr.Add_int_fixed(val, val_len);
|
|
bfr.Add_byte_repeat(pad_chr, pad_len);
|
|
if (bgn)
|
|
bfr.Add_int_fixed(val, val_len);
|
|
|
|
return bfr.To_str();
|
|
}
|
|
public static String To_str_hex(int v) {return To_str_hex(Bool_.Y, Bool_.Y, v);}
|
|
public static String To_str_hex(boolean zero_pad, boolean upper, int v) {
|
|
String rv = Integer.toHexString(v);
|
|
int rv_len = String_.Len(rv);
|
|
if (zero_pad && rv_len < 8) rv = String_.Repeat("0", 8 - rv_len) + rv;
|
|
return upper ? String_.Upper(rv) : rv;
|
|
}
|
|
|
|
public static int Compare(int lhs, int rhs) {
|
|
if (lhs == rhs) return CompareAble_.Same;
|
|
else if (lhs < rhs) return CompareAble_.Less;
|
|
else return CompareAble_.More;
|
|
}
|
|
public static boolean In(int v, int comp0, int comp1) {return v == comp0 || v == comp1;}
|
|
public static boolean In(int v, int... ary) {
|
|
for (int itm : ary)
|
|
if (v == itm) return true;
|
|
return false;
|
|
}
|
|
public static boolean Between(int v, int lhs, int rhs) {
|
|
int lhsCompare = v == lhs ? 0 : (v < lhs ? -1 : 1);
|
|
int rhsCompare = v == rhs ? 0 : (v < rhs ? -1 : 1);
|
|
return (lhsCompare * rhsCompare) != 1; // 1 when v is (a) greater than both or (b) less than both
|
|
}
|
|
public static boolean RangeCheck(int v, int max) {return v >= 0 && v < max;}
|
|
public static void RangeCheckOrFail_list(int v, int max, String s) {if (v < 0 || v >= max) throw Err_.new_wo_type("bounds check failed", "msg", s, "v", v, "min", 0, "max", max - 1);}
|
|
public static boolean Bounds_chk(int bgn, int end, int len) {return bgn > -1 && end < len;}
|
|
public static int BoundEnd(int v, int end) {return v >= end ? end - 1 : v;}
|
|
public static int EnsureLessThan(int v, int max) {return v >= max ? max : v;}
|
|
|
|
public static int Min(int lhs, int rhs) {return lhs < rhs ? lhs : rhs;}
|
|
public static int Max(int lhs, int rhs) {return lhs > rhs ? lhs : rhs;}
|
|
public static int Min_many(int... ary) {
|
|
int len = ary.length; if (len == 0) throw Err_.new_wo_type("Min_many requires at least 1 value");
|
|
boolean init = true;
|
|
int min = Int_.Min_value;
|
|
for (int i = 0; i < len; ++i) {
|
|
int val = ary[i];
|
|
if (init) {
|
|
min = val;
|
|
init = false;
|
|
}
|
|
else {
|
|
if (val < min)
|
|
min = val;
|
|
}
|
|
}
|
|
return min;
|
|
}
|
|
|
|
public static int Subtract_long(long lhs, long rhs) {return (int)(lhs - rhs);}
|
|
public static int Div(int v, float divisor) {return (int)((float)v / divisor);}
|
|
public static int DivAndRoundUp(int v, int divisor) {
|
|
int whole = v / divisor;
|
|
int partial = v % divisor == 0 ? 0 : 1;
|
|
return whole + partial;
|
|
}
|
|
public static int Mult(int v, float multiplier) {
|
|
float product = ((float)v * multiplier); // WORKAROUND (DotNet): (int)((float)v * multiplier) returns 0 for 100 and .01f
|
|
return (int)product;
|
|
}
|
|
|
|
public static int[] Log10Ary = new int[] {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, Int_.Max_value};
|
|
public static int Log10AryLen = 11;
|
|
public static int Log10(int v) {
|
|
if (v == 0) return 0;
|
|
int sign = 1;
|
|
if (v < 0) {
|
|
if (v == Int_.Min_value) return -9; // NOTE: Int_.Min_value * -1 = Int_.Min_value
|
|
v *= -1;
|
|
sign = -1;
|
|
}
|
|
int rv = Log10AryLen - 2; // rv will only happen when v == Int_.Max_value
|
|
int bgn = 0;
|
|
if (v > 1000) { // optimization to reduce number of ops to < 5
|
|
bgn = 3;
|
|
if (v > 1000000) bgn = 6;
|
|
}
|
|
for (int i = bgn; i < Log10AryLen; i++) {
|
|
if (v < Log10Ary[i]) {rv = i - 1; break;}
|
|
}
|
|
return rv * sign;
|
|
}
|
|
|
|
public static int DigitCount(int v) {
|
|
int log10 = Log10(v);
|
|
return v > -1 ? log10 + 1 : log10 * -1 + 2;
|
|
}
|
|
}
|