-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#54 step-1(Define Sub-units of Xdager)
- Loading branch information
Showing
4 changed files
with
299 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
package io.xdag.core; | ||
|
||
import io.xdag.utils.BasicUtils; | ||
|
||
import java.math.BigDecimal; | ||
|
||
import static java.math.RoundingMode.FLOOR; | ||
import static java.math.RoundingMode.HALF_UP; | ||
|
||
public class XAmount implements Comparable<XAmount> { | ||
|
||
public static final XAmount ZERO = new XAmount(0); | ||
public static final XAmount ONE = new XAmount(1); | ||
public static final XAmount TEN = new XAmount(10); | ||
|
||
private final long nano; | ||
|
||
private XAmount(long nano) { | ||
this.nano = nano; | ||
} | ||
|
||
public static XAmount of(long n) { | ||
return new XAmount(n); | ||
} | ||
|
||
public static XAmount of(String n) { | ||
return new XAmount(Long.parseLong(n)); | ||
} | ||
|
||
public static XAmount of(long n, XUnit unit) throws ArithmeticException { | ||
return new XAmount(Math.multiplyExact(n, unit.factor)); | ||
} | ||
|
||
public static XAmount of(BigDecimal d, XUnit unit) { | ||
return new XAmount(d.movePointRight(unit.exp).setScale(0, FLOOR).longValueExact()); | ||
} | ||
|
||
public BigDecimal toDecimal(int scale, XUnit unit) { | ||
BigDecimal nano = BigDecimal.valueOf(this.nano); | ||
return nano.movePointLeft(unit.exp).setScale(scale, FLOOR); | ||
} | ||
|
||
/** | ||
* Of Xdag Amount from C | ||
*/ | ||
public static XAmount ofXAmount(long n) { | ||
BigDecimal d = BasicUtils.amount2xdagNew(n) ; | ||
return new XAmount(d.movePointRight(9).setScale(0, HALF_UP).longValueExact()); | ||
} | ||
|
||
/** | ||
* To Xdag Amount from C | ||
*/ | ||
public long toXAmount() { | ||
return BasicUtils.xdag2amount(toDecimal(9, XUnit.XDAG).doubleValue()); | ||
} | ||
|
||
@Override | ||
public int compareTo(XAmount other) { | ||
return this.lessThan(other) ? -1 : (this.greaterThan(other) ? 1 : 0); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Long.hashCode(nano); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object other) { | ||
return other instanceof XAmount && ((XAmount) other).nano == nano; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return String.valueOf(nano); | ||
} | ||
|
||
public boolean greaterThan(XAmount other) { | ||
return nano > other.nano; | ||
} | ||
|
||
public boolean greaterThanOrEqual(XAmount other) { | ||
return nano >= other.nano; | ||
} | ||
|
||
public boolean isPositive() { | ||
return greaterThan(ZERO); | ||
} | ||
|
||
public boolean isNotNegative() { | ||
return greaterThanOrEqual(ZERO); | ||
} | ||
|
||
public boolean lessThan(XAmount other) { | ||
return nano < other.nano; | ||
} | ||
|
||
public boolean lessThanOrEqual(XAmount other) { | ||
return nano <= other.nano; | ||
} | ||
|
||
public boolean isNegative() { | ||
return lessThan(ZERO); | ||
} | ||
|
||
public boolean isNotPositive() { | ||
return lessThanOrEqual(ZERO); | ||
} | ||
|
||
public XAmount negate() throws ArithmeticException { | ||
return new XAmount(Math.negateExact(this.nano)); | ||
} | ||
|
||
public XAmount add(XAmount a) throws ArithmeticException { | ||
return new XAmount(Math.addExact(this.nano, a.nano)); | ||
} | ||
|
||
public XAmount subtract(XAmount a) throws ArithmeticException { | ||
return new XAmount(Math.subtractExact(this.nano, a.nano)); | ||
} | ||
|
||
public XAmount multiply(long a) throws ArithmeticException { | ||
return new XAmount(Math.multiplyExact(this.nano, a)); | ||
} | ||
|
||
public static XAmount sum(XAmount a, XAmount b) throws ArithmeticException { | ||
return new XAmount(Math.addExact(a.nano, b.nano)); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package io.xdag.core; | ||
|
||
import static java.util.Arrays.stream; | ||
import java.math.BigInteger; | ||
|
||
public enum XUnit { | ||
|
||
NANO_XDAG(0, "nXDAG"), | ||
|
||
MICRO_XDAG(3, "μXDAG"), | ||
|
||
MILLI_XDAG(6, "mXDAG"), | ||
|
||
XDAG(9, "XDAG"); | ||
|
||
public final int exp; | ||
public final long factor; | ||
public final String symbol; | ||
|
||
XUnit(int exp, String symbol) { | ||
this.exp = exp; | ||
this.factor = BigInteger.TEN.pow(exp).longValueExact(); | ||
this.symbol = symbol; | ||
} | ||
|
||
/** | ||
* Decode the unit from symbol. | ||
* | ||
* @param symbol | ||
* the symbol text | ||
* @return a Unit object if valid; otherwise false | ||
*/ | ||
public static XUnit of(String symbol) { | ||
return stream(values()).filter(v -> v.symbol.equals(symbol)).findAny().orElse(null); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
package io.xdag.core; | ||
|
||
import org.junit.Test; | ||
|
||
import java.math.BigDecimal; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertFalse; | ||
import static org.junit.Assert.assertNull; | ||
import static org.junit.Assert.assertTrue; | ||
|
||
import static io.xdag.core.XUnit.NANO_XDAG; | ||
import static io.xdag.core.XUnit.MICRO_XDAG; | ||
import static io.xdag.core.XUnit.MILLI_XDAG; | ||
import static io.xdag.core.XUnit.XDAG; | ||
import static io.xdag.core.XAmount.ZERO; | ||
|
||
public class XAmountTest { | ||
|
||
@Test | ||
public void testUnits() { | ||
assertEquals(ZERO, ZERO); | ||
assertEquals(XAmount.of(1), XAmount.of(1)); | ||
assertEquals(XAmount.of(1000), XAmount.of(1, MICRO_XDAG)); | ||
assertEquals(XAmount.of(1000, MICRO_XDAG), XAmount.of(1, MILLI_XDAG)); | ||
assertEquals(XAmount.of(1000, MILLI_XDAG), XAmount.of(1, XDAG)); | ||
} | ||
|
||
@Test | ||
public void testFromDecimal() { | ||
assertEquals(ZERO, XAmount.of(BigDecimal.ZERO, XDAG)); | ||
assertEquals(XAmount.of(10, XDAG), XAmount.of(new BigDecimal("10.000"), XDAG)); | ||
} | ||
|
||
@Test | ||
public void testFromSymbol() { | ||
assertEquals(NANO_XDAG, XUnit.of("nXDAG")); | ||
assertEquals(MICRO_XDAG, XUnit.of("μXDAG")); | ||
assertEquals(MILLI_XDAG, XUnit.of("mXDAG")); | ||
assertEquals(XDAG, XUnit.of("XDAG")); | ||
} | ||
|
||
@Test | ||
public void testFromSymbolUnknown() { | ||
assertNull(XUnit.of("???")); | ||
} | ||
|
||
@Test | ||
public void testToDecimal() { | ||
assertEquals(new BigDecimal("0"), ZERO.toDecimal(0, XDAG)); | ||
assertEquals(new BigDecimal("0.000"), ZERO.toDecimal(3, XDAG)); | ||
|
||
XAmount oneXdag = XAmount.of(1, XDAG); | ||
assertEquals(new BigDecimal("1.000"), oneXdag.toDecimal(3, XDAG)); | ||
assertEquals(new BigDecimal("1000.000"), oneXdag.toDecimal(3, MILLI_XDAG)); | ||
} | ||
|
||
@Test | ||
public void testCompareTo() { | ||
assertEquals(ZERO.compareTo(ZERO), 0); | ||
assertEquals(XAmount.of(1000).compareTo(XAmount.of(1, MICRO_XDAG)), 0); | ||
|
||
assertEquals(XAmount.of(10).compareTo(XAmount.of(10)), 0); | ||
assertEquals(XAmount.of(5).compareTo(XAmount.of(10)), -1); | ||
assertEquals(XAmount.of(10).compareTo(XAmount.of(5)), 1); | ||
} | ||
|
||
@Test | ||
public void testHashCode() { | ||
assertEquals(ZERO.hashCode(), XAmount.of(0, XDAG).hashCode()); | ||
assertEquals(XAmount.of(999, XDAG).hashCode(), XAmount.of(999, XDAG).hashCode()); | ||
} | ||
|
||
@Test | ||
public void testGtLtEtc() { | ||
assertTrue(XAmount.of(19, XDAG).isPositive()); | ||
assertTrue(XAmount.of(-9, XDAG).isNegative()); | ||
assertFalse(ZERO.isPositive()); | ||
assertFalse(ZERO.isNegative()); | ||
|
||
assertTrue(ZERO.isNotNegative()); | ||
assertTrue(ZERO.isNotPositive()); | ||
assertFalse(XAmount.of(-9, XDAG).isNotNegative()); | ||
assertFalse(XAmount.of(99, XDAG).isNotPositive()); | ||
|
||
assertTrue(XAmount.of(999, XDAG).greaterThan(XAmount.of(999, MILLI_XDAG))); | ||
assertTrue(XAmount.of(999, XDAG).greaterThanOrEqual(XAmount.of(999, MILLI_XDAG))); | ||
assertFalse(XAmount.of(999, XDAG).lessThan(XAmount.of(999, MILLI_XDAG))); | ||
assertFalse(XAmount.of(999, XDAG).lessThanOrEqual(XAmount.of(999, MILLI_XDAG))); | ||
} | ||
|
||
@Test | ||
public void TestAmount2xdag() { | ||
assertEquals(972.80, XAmount.ofXAmount(4178144185548L).toDecimal(2, XDAG).doubleValue(), 0.0); | ||
|
||
// 3333333334 | ||
assertEquals(51.20, XAmount.ofXAmount(219902325556L).toDecimal(2, XDAG).doubleValue(), 0.0); | ||
|
||
// 400 0000 0000? | ||
assertEquals(1.49, XAmount.ofXAmount(6400000000L).toDecimal(2, XDAG).doubleValue(), 0.0); | ||
|
||
// Xfer:transferred 44796588980 10.430000000 XDAG to the address 0000002f28322e9d817fd94a1357e51a. 10.43 | ||
assertEquals(10.43, XAmount.ofXAmount(44796588980L).toDecimal(2, XDAG).doubleValue(), 0.0); | ||
|
||
// Xfer:transferred 42949672960 10.000000000 XDAG to the address 0000002f28322e9d817fd94a1357e51a. 10.00 | ||
assertEquals(10.00, XAmount.ofXAmount(42949672960L).toDecimal(2, XDAG).doubleValue(), 0.0); | ||
|
||
// Xfer:transferred 4398046511104 1024.000000000 XDAG to the address 0000002f28322e9d817fd94a1357e51a. 1024.00 | ||
assertEquals(1024.00, XAmount.ofXAmount(4398046511104L).toDecimal(2, XDAG).doubleValue(), 0.0); | ||
} | ||
|
||
@Test | ||
public void TestXdag2amount() { | ||
BigDecimal a = BigDecimal.valueOf(972.80); | ||
assertEquals(4178144185549L, XAmount.of(a, XDAG).toXAmount()); | ||
|
||
BigDecimal b = BigDecimal.valueOf(51.20); | ||
assertEquals(219902325556L, XAmount.of(b, XDAG).toXAmount()); | ||
|
||
BigDecimal c = BigDecimal.valueOf(100.00); | ||
assertEquals(429496729600L, XAmount.of(c, XDAG).toXAmount()); | ||
} | ||
|
||
} |