debugjavaModerate
BigDecimal made simple
Viewed 0 times
simplemadebigdecimal
Problem
Here is my take on (a lighter version of) Java's
```
public class SimpleDecimal implements Comparable {
private long value = 0L;
private int fractionalPrecision = 0;
private boolean debug = false;
public static SimpleDecimal simplify(SimpleDecimal o) {
if (!((o.getFractionalPrecision() > 0) && ((o.getValue() % 10) == 0))) {
return o;
}
SimpleDecimal sd = new SimpleDecimal(o);
do {
sd.setValue(sd.getValue() / 10);
sd.setFractionalPrecision(sd.getFractionalPrecision() - 1);
} while ((sd.getFractionalPrecision() > 0) && ((sd.getValue() % 10) == 0));
return sd;
}
public static SimpleDecimal adjust(SimpleDecimal o, int fractionalPrecision) {
if (o.getFractionalPrecision() == fractionalPrecision) {
return o;
}
if (o.getFractionalPrecision() > fractionalPrecision) {
return simplify(o);
}
SimpleDecimal sd = new SimpleDecimal(o);
sd.incFractionalPrecision(fractionalPrecision - sd.getFractionalPrecision());
return sd;
}
// Various constructors
public SimpleDecimal(int value) {
this(String.valueOf(value));
}
public SimpleDecimal(long value) {
this(String.valueOf(value));
}
public SimpleDecimal(float value) {
this(String.valueOf(value));
}
public SimpleDecimal(double value) {
this(String.valueOf(value));
}
/**
* This method will expect standard representation of numerical value as returned by
* String.valueOf(...)
* @param value
*/
public SimpleDecimal(String value) {
int fpsl = value.lastIndexOf('.');
String strValue;
if (fpsl > 0) {
strValue = value.substring(0, fpsl) + value.substring(fpsl
BigDecimal. I originally wrote this as a replacement for BigDecimal in order to improve performance during serialisation and data manipulation.```
public class SimpleDecimal implements Comparable {
private long value = 0L;
private int fractionalPrecision = 0;
private boolean debug = false;
public static SimpleDecimal simplify(SimpleDecimal o) {
if (!((o.getFractionalPrecision() > 0) && ((o.getValue() % 10) == 0))) {
return o;
}
SimpleDecimal sd = new SimpleDecimal(o);
do {
sd.setValue(sd.getValue() / 10);
sd.setFractionalPrecision(sd.getFractionalPrecision() - 1);
} while ((sd.getFractionalPrecision() > 0) && ((sd.getValue() % 10) == 0));
return sd;
}
public static SimpleDecimal adjust(SimpleDecimal o, int fractionalPrecision) {
if (o.getFractionalPrecision() == fractionalPrecision) {
return o;
}
if (o.getFractionalPrecision() > fractionalPrecision) {
return simplify(o);
}
SimpleDecimal sd = new SimpleDecimal(o);
sd.incFractionalPrecision(fractionalPrecision - sd.getFractionalPrecision());
return sd;
}
// Various constructors
public SimpleDecimal(int value) {
this(String.valueOf(value));
}
public SimpleDecimal(long value) {
this(String.valueOf(value));
}
public SimpleDecimal(float value) {
this(String.valueOf(value));
}
public SimpleDecimal(double value) {
this(String.valueOf(value));
}
/**
* This method will expect standard representation of numerical value as returned by
* String.valueOf(...)
* @param value
*/
public SimpleDecimal(String value) {
int fpsl = value.lastIndexOf('.');
String strValue;
if (fpsl > 0) {
strValue = value.substring(0, fpsl) + value.substring(fpsl
Solution
Your assertion that this is a replacement for BigDecimal, is.... ambitious.
You are limited to about 18 significant figures, and your code will throw odd exceptions for values that exceed that will throw a NumberFormatException, as far as I can tell.
Additionally, your class is not immutable, which is slightly concerning, since by convention, Java
You override the
The
The
If the o's precision is greater than the input, you simplify it, but, simplify may do nothing..... so, the adjust does nothing? Also, what is it adjusting? The method is badly named, and I suspect it should just go away.
Your class does not extend
Your primitive-based constructors do things the wrong way around... they all convert the primitives to String, then convert the string back to the source value. This is slow. You should be converting directly to long, and then have a more comprehensive String constructor.
All your arithmetic methods are adjusting the values to be stored in the SimpleDecimal as the calculation is done. This is against the immutable concept for Java numbers. You should instead calculate what the number-parts should be, and then construct the final result from those parts with no additional adjustment.
One final observation, your code is not what I would consider to be 'production ready'. It does not deal with common issues that arise, like, the value
You are limited to about 18 significant figures, and your code will throw odd exceptions for values that exceed that will throw a NumberFormatException, as far as I can tell.
Additionally, your class is not immutable, which is slightly concerning, since by convention, Java
Number classes are immutable.You override the
equals method, but do not override the hashCode() method, which means you cannot safely use this value in a HashSet, HashMap, or many other constructs.The
simplify method is duplicated as both a public static method, as well as an instance method. There should be only one (the instance method, I presume), or the other should not be public.The
adjust method looks broken:public static SimpleDecimal adjust(SimpleDecimal o, int fractionalPrecision) {
if (o.getFractionalPrecision() == fractionalPrecision) {
return o;
}
if (o.getFractionalPrecision() > fractionalPrecision) {
return simplify(o);
}
SimpleDecimal sd = new SimpleDecimal(o);
sd.incFractionalPrecision(fractionalPrecision - sd.getFractionalPrecision());
return sd;
}If the o's precision is greater than the input, you simplify it, but, simplify may do nothing..... so, the adjust does nothing? Also, what is it adjusting? The method is badly named, and I suspect it should just go away.
Your class does not extend
java.lang.Number. This is not really essential, but, it would be nice.Your primitive-based constructors do things the wrong way around... they all convert the primitives to String, then convert the string back to the source value. This is slow. You should be converting directly to long, and then have a more comprehensive String constructor.
All your arithmetic methods are adjusting the values to be stored in the SimpleDecimal as the calculation is done. This is against the immutable concept for Java numbers. You should instead calculate what the number-parts should be, and then construct the final result from those parts with no additional adjustment.
One final observation, your code is not what I would consider to be 'production ready'. It does not deal with common issues that arise, like, the value
-.01 should be legal, but I believe will cause your code to fail, and fail in a consistent way with other failure modes. Additionally, I have, in the past, attempted to write a mutable-version of BigDecimal to reduce the memory impact it has.... and failed. The code is complex, and I fear your SimpleDecimal has oversimplified too many things, and made too many compromises and assumptions.Code Snippets
public static SimpleDecimal adjust(SimpleDecimal o, int fractionalPrecision) {
if (o.getFractionalPrecision() == fractionalPrecision) {
return o;
}
if (o.getFractionalPrecision() > fractionalPrecision) {
return simplify(o);
}
SimpleDecimal sd = new SimpleDecimal(o);
sd.incFractionalPrecision(fractionalPrecision - sd.getFractionalPrecision());
return sd;
}Context
StackExchange Code Review Q#62436, answer score: 11
Revisions (0)
No revisions yet.