我将字符串作为程序的输入,但这些可以用各种格式表示。 E.g:
所有这些数字在数学上,以下程序也会说明匹配:
public class BigDecimalMain {
public static void main(String... args) {
BigDecimal a = new BigDecimal("8900");
BigDecimal b = new BigDecimal("8.9E+3");
BigDecimal c = new BigDecimal("89E+2");
BigDecimal d = new BigDecimal("8900.000");
System.out.println(a.compareTo(b));
System.out.println(a.compareTo(c));
System.out.println(a.compareTo(d));
}
}
输出:
0
0
0
我的程序使用 .equals 匹配对象,但在上述情况下无法给出正确的答案。
问题:如何将字符串统一解析为BigDecimal?我的意思是:
find a function PARSE, that
for any STR1 && STR2
PARSE(STR1).compareTo(PARSE(STR2)) == 0 <=> PARSE(STR1).equals(PARSE(STR2))
答案 0 :(得分:2)
使用通用比例,您可以使用setScale(xxx):
{
BigDecimal a = new BigDecimal("8900");
BigDecimal b = new BigDecimal("8.9E+3");
BigDecimal c = new BigDecimal("89E+2");
BigDecimal d = new BigDecimal("8900.000");
System.out.println(a.compareTo(b));
System.out.println(a.compareTo(c));
System.out.println(a.compareTo(d));
System.out.println(a.equals(b));
System.out.println(a.equals(c));
System.out.println(a.equals(d));
}
{
BigDecimal a = new BigDecimal("8900").setScale(5);
BigDecimal b = new BigDecimal("8.9E+3").setScale(5);
BigDecimal c = new BigDecimal("89E+2").setScale(5);
BigDecimal d = new BigDecimal("8900.000").setScale(5);
System.out.println(a.compareTo(b));
System.out.println(a.compareTo(c));
System.out.println(a.compareTo(d));
System.out.println(a.equals(b));
System.out.println(a.equals(c));
System.out.println(a.equals(d));
}
显示
0
0
0
false
false
false
0
0
0
true
true
true
答案 1 :(得分:2)
考虑以下方法:
class UniformDecimal {
private final BigDecimal decimal;
public UniformDecimal(BigDecimal decimal) {
this.decimal = decimal;
}
@Override
public int hashCode() {
return decimal.toBigInteger().mod(BigInteger.valueOf((1<<31)-1)).intValue();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UniformDecimal that = (UniformDecimal) o;
return that.decimal.compareTo(this.decimal)==0;
}
}
虽然,我不确定hashCode的实现
答案 2 :(得分:0)
更新。似乎stripTrailingZeros()做了这件事!
在此处找到有用的内容:HiveDecimal
private static BigDecimal normalize(BigDecimal bd, boolean allowRounding) {
if (bd == null) {
return null;
}
bd = trim(bd);
int intDigits = bd.precision() - bd.scale();
if (intDigits > MAX_PRECISION) {
return null;
}
int maxScale = Math.min(MAX_SCALE, Math.min(MAX_PRECISION - intDigits, bd.scale()));
if (bd.scale() > maxScale) {
if (allowRounding) {
bd = bd.setScale(maxScale, RoundingMode.HALF_UP);
// Trimming is again necessary, because rounding may introduce new trailing 0's.
bd = trim(bd);
} else {
bd = null;
}
}
return bd;
}
private static BigDecimal trim(BigDecimal d) {
if (d.compareTo(BigDecimal.ZERO) == 0) {
// Special case for 0, because java doesn't strip zeros correctly on that number.
d = BigDecimal.ZERO;
} else {
d = d.stripTrailingZeros();
if (d.scale() < 0) {
// no negative scale decimals
d = d.setScale(0);
}
}
return d;
}