Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ERXMoney #471

Merged
merged 11 commits into from
Aug 29, 2013
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package er.extensions.foundation;

import java.math.BigDecimal;

import er.extensions.enums.ERXMoneyEnums;

/**
Expand All @@ -25,9 +27,13 @@ public ERXMoney(final ERXMoney x) {
value = x.value;
}

public ERXMoney(final double x, ERXMoneyEnums money) {
value = Math.round(x * money.scale());
this.money = money;
public ERXMoney(final BigDecimal x, ERXMoneyEnums currency) {
this(x.doubleValue(), currency);
}

public ERXMoney(final double x, ERXMoneyEnums currency) {
value = Math.round(x * currency.scale());
this.money = currency;
}

//********************************************************************
Expand All @@ -39,6 +45,11 @@ public ERXMoney set(final double rs) {
return this;
}

public ERXMoney set(final BigDecimal rs) {
value = Math.round(rs.doubleValue() * money.scale());
return this;
}

public ERXMoney set(final ERXMoney rs) {
value = rs.value;
return this;
Expand All @@ -48,12 +59,18 @@ public ERXMoney set(final ERXMoney rs) {
// Accessors
//********************************************************************

public long wholeUnits() {
public long wholeUnits() {
return value / money.scale();
}

public short cents () {
return (short)((value * 100) / money.scale() - (100 * wholeUnits()));
public short cents() {
return (short) ((value * 100) / money.scale() - (100 * wholeUnits()));
}

public BigDecimal asBigDecimal() {
int centScale = log10(money.scale());
String centString = "00000000" + cents();
return new BigDecimal(wholeUnits() + "." + centString.substring(centString.length() - centScale, centString.length()));
}

//********************************************************************
Expand All @@ -68,30 +85,30 @@ public ERXMoney abs() {
}

public short sign() {
return (short)(value > 0 ? 1 : value < 0 ? -1 : 0);
return (short) (value > 0 ? 1 : value < 0 ? -1 : 0);
}

//********************************************************************
// Relational (predicate) operations
//********************************************************************

public boolean equals (final ERXMoney rs) {
public boolean equals(final ERXMoney rs) {
return value == rs.value;
}
public boolean lessThan (final ERXMoney rs) {
public boolean lessThan(final ERXMoney rs) {
return value < rs.value;
}
public boolean greaterThan (final ERXMoney rs) {
public boolean greaterThan(final ERXMoney rs) {
return value > rs.value;
}

public boolean equals (final double rs) {
public boolean equals(final double rs) {
return value == rs * money.scale();
}
public boolean lessThan (final double rs) {
public boolean lessThan(final double rs) {
return value < rs * money.scale();
}
public boolean greaterThan (final double rs) {
public boolean greaterThan(final double rs) {
return value > rs * money.scale();
}

Expand All @@ -100,90 +117,118 @@ public boolean greaterThan (final double rs) {
//********************************************************************

@Override
public boolean equals (final Object rs) {
return rs instanceof ERXMoney && ((ERXMoney)rs).value == value;
public boolean equals(final Object rs) {
return (rs instanceof ERXMoney) && (((ERXMoney) rs).value == value);
}

public int compareTo (final Object rs) {
return sub((ERXMoney)rs).sign();
public int compareTo(final Object rs) {
return sub((ERXMoney) rs).sign();
}

@Override
public int hashCode () {
public int hashCode() {
return (Long.valueOf(value)).hashCode();
}

//********************************************************************
// Arithmetic operations
//********************************************************************

public ERXMoney addSet (final ERXMoney rs) {
public ERXMoney addSet(final ERXMoney rs) {
value += rs.value;
return this;
}
public ERXMoney addSet (final double rs) {
public ERXMoney addSet(final double rs) {
value += rs * money.scale();
return this;
}
public ERXMoney subSet (final ERXMoney rs) {
public ERXMoney addSet(final BigDecimal rs) {
value += rs.doubleValue() * money.scale();
return this;
}

public ERXMoney subSet(final ERXMoney rs) {
value -= rs.value;
return this;
}
public ERXMoney subSet (final double rs){
public ERXMoney subSet(final double rs){
value -= rs * money.scale();
return this;
}
public ERXMoney mpySet (final ERXMoney rs) {
public ERXMoney subSet(final BigDecimal rs){
value -= rs.doubleValue() * money.scale();
return this;
}

public ERXMoney mpySet(final ERXMoney rs) {
value *= rs.value;
return this;
}
public ERXMoney mpySet (final double rs) {
public ERXMoney mpySet(final double rs) {
value *= rs;
return this;
}
public ERXMoney divSet (final ERXMoney rs) {
Math.round(value /= rs.value);
return this;
public ERXMoney mpySet(final BigDecimal rs) {
value *= rs.doubleValue();
return this;
}
public ERXMoney divSet (final double rs) {
Math.round(value /= rs);
return this;

public ERXMoney divSet(final ERXMoney rs) {
value = Math.round(value / rs.value);
return this;
}
public ERXMoney divSet(final double rs) {
value = Math.round(value / rs);
return this;
}
public ERXMoney divSet(final BigDecimal rs) {
value = Math.round(value / rs.doubleValue());
return this;
}

public ERXMoney percentSet(final double rs) {
value = Math.round((double) value / 100 * rs);
return this;
}
public ERXMoney percentSet(final BigDecimal rs) {
value = Math.round((double) value / 100 * rs.doubleValue());
return this;
}

public ERXMoney minusSet() {
value = - value;
return this;
}

public ERXMoney add (final ERXMoney rs) {
public ERXMoney add(final ERXMoney rs) {
return new ERXMoney(this).addSet(rs);
}
public ERXMoney add (final double rs) {
public ERXMoney add(final double rs) {
return new ERXMoney(this).addSet(rs);
}

public ERXMoney sub (final ERXMoney rs) {
public ERXMoney sub(final ERXMoney rs) {
return new ERXMoney(this).subSet(rs);
}
public ERXMoney sub (final double rs) {
public ERXMoney sub(final double rs) {
return new ERXMoney(this).subSet(rs);
}

public ERXMoney mpy (final ERXMoney rs) {
public ERXMoney mpy(final ERXMoney rs) {
return new ERXMoney(this).mpySet(rs);
}
public ERXMoney mpy (final double rs) {
public ERXMoney mpy(final double rs) {
return new ERXMoney(this).mpySet(rs);
}

public ERXMoney div (final ERXMoney rs) {
public ERXMoney div(final ERXMoney rs) {
return new ERXMoney(this).divSet(rs);
}
public ERXMoney div (final double rs) {
public ERXMoney div(final double rs) {
return new ERXMoney(this).divSet(rs);
}

public ERXMoney minus() {
public ERXMoney minus() {
return new ERXMoney(this).minusSet();
}

Expand All @@ -193,56 +238,63 @@ public ERXMoney minus() {

private static short log10(long x) {
short result; // of decimal digits in an integer
for (result=0; x>=10; result++, x/=10); // Decimal "shift" and count
for (result=0; x>=10; result++, x/=10) {
// Decimal "shift" and count
}
return result;
}

@Override
public String toString () {
boolean negative = (value < 0); // Remember original sign
value = negative ? -value : value; // Discard sign temporarily
long whole = wholeUnits(); // Separate arg. into whole
short cents = cents(); // and fractional monetary units
short rest = (short)(value - (cents + 100 * whole) * money.scale() / 100);
public String toString() {
boolean negative = (value < 0); // Remember original sign
value = negative ? -value : value; // Discard sign temporarily
long whole = wholeUnits(); // Separate arg. into whole
short cents = cents(); // and fractional monetary units
short rest = (short) (value - (cents + 100 * whole) * money.scale() / 100);

String result = (negative ? "-" : ""); // Insert prefix minus, if needed
result = result + money.prefixSymbol(); // Insert dollar sign or equiv.
String result = (negative ? "-" : ""); // Insert prefix minus, if needed
result = result + money.prefixSymbol(); // Insert dollar sign or equiv.

long divisors[] = { 1, 1000, 1000000, (long)1E9, (long)1E12,(long)1E15, (long)1E18};
long divisors[] = { 1, 1000, 1000000, (long) 1E9, (long) 1E12,(long) 1E15, (long) 1E18 };
int group_no = log10(whole) / 3;
int group_val = (int)(whole / divisors[group_no]);

result = result + group_val; // Append leftmost 3-digits
result = result + group_val; // Append leftmost 3-digits

while (group_no > 0) { // For each remaining 3-digit group
result = result + money.group_separator(); // Insert punctuation
while (group_no > 0) { // For each remaining 3-digit group
result = result + money.group_separator(); // Insert punctuation
whole -= group_val * divisors[group_no--]; // Compute new remainder
group_val = (short)(whole/divisors[group_no]); // Get next 3-digit value
if (group_val < 100)
result = result + "0"; // Insert embedded 0's
if (group_val < 10)
result = result + "0"; // as needed
result = result + group_val; // Append group value
group_val = (short) (whole/divisors[group_no]); // Get next 3-digit value
if (group_val < 100) {
result = result + "0"; // Insert embedded 0's
}
if (group_val < 10) {
result = result + "0"; // as needed
}
result = result + group_val; // Append group value
}

// Append the fractional portion
// Append the fractional portion
if(money.scale() > 1) {
result = result + money.decimal_point(); // Append decimal point
result = result + money.decimal_point(); // Append decimal point

int centScale = log10(money.scale());
String centString = "00000000" + cents;

// Append cents value
// Append cents value
result += centString.substring(centString.length() - centScale, centString.length());
}

if (rest > 0) { // Test for fractional pennies
while ((rest *= 10) < money.scale()); // (rest *= power(10,log10(money.scale())))
result = result + (rest/money.scale()); // Append fractional pennies, if any
if (rest > 0) { // Test for fractional pennies
while ((rest *= 10) < money.scale()) {
// (rest *= power(10,log10(money.scale())))
}
result = result + (rest/money.scale()); // Append fractional pennies, if any
}
if (negative) // Restore original sign
if (negative) { // Restore original sign
value = - value;

return result + money.suffixSymbol(); // Append final symbol, if any
}

return result + money.suffixSymbol(); // Append final symbol, if any
}
}