Add more decimal calculations
This commit is contained in:
parent
3f229dca29
commit
93845890c1
@ -44,7 +44,27 @@ public class Util {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void getIncrement(Identifier[] i1, Identifier[] i2, int offset) {
|
public static int[] getIncremented(Identifier[] i1, Identifier[] i2, int offset) {
|
||||||
|
// TODO: can potentially be optimized by just calculating the index of the first non-zero digit (e.g. don't return array and discard it -> just return the index)
|
||||||
|
int[] delta = subtract(i2, i1, offset);
|
||||||
|
int firstNonZero = 0;
|
||||||
|
for(int i = 0; i < delta.length; i++) {
|
||||||
|
if(delta[i] != 0) {
|
||||||
|
firstNonZero = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Because of math, (firstNonZero + 1) >= i1.length (I think)
|
||||||
|
// then make the array 1 longer so we have space for the increment (which is one order of magnitude smaller)
|
||||||
|
int[] incremented = new int[firstNonZero + 2];
|
||||||
|
for(int i = 0; i < incremented.length; i++) {
|
||||||
|
incremented[i] = i <= i1.length ? i1[i].digit() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
add1AtIndex(incremented, firstNonZero + 1); // last digit might be zero, which is ambigious, inc again
|
||||||
|
if(incremented[incremented.length - 1] == 0) add1AtIndex(incremented, firstNonZero + 1);
|
||||||
|
return incremented;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,7 +87,26 @@ public class Util {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(carry == 1) throw new RuntimeException("Can't subtract numbers (are you sure a > b?)");
|
||||||
|
|
||||||
return diff;
|
return diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void add1AtIndex(int[] a, int index) {
|
||||||
|
// Technically, some of the overflow preventions are probably overkill since the biggest carry we can get is 1 (we're only adding a 1 somewhere after all)
|
||||||
|
|
||||||
|
int carry = 0;
|
||||||
|
for(int i = a.length - 1; i >= 0; i--) {
|
||||||
|
int dA = a[i];
|
||||||
|
int dB = (index == i ? 1 : 0) + carry;
|
||||||
|
|
||||||
|
carry = dB - (BASE - dA) + 1; // Calculate carry and be overflow-safe
|
||||||
|
if(carry < 0) carry = 0;
|
||||||
|
|
||||||
|
a[i] = carry != 0 ? -BASE + dA + dB : dA + dB; // Calculate sum of digits and be overflow-safe
|
||||||
|
}
|
||||||
|
|
||||||
|
if(carry == 1) throw new RuntimeException("Can't add numbers: Too large");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package me.mrletsplay.shareclientcore;
|
package me.mrletsplay.shareclientcore;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
@ -13,21 +14,56 @@ public class DecimalTest {
|
|||||||
public void testSimpleSubtraction() {
|
public void testSimpleSubtraction() {
|
||||||
Identifier[] a = new Identifier[] { new Identifier(1, 0), new Identifier(2, 0), new Identifier(3, 0) };
|
Identifier[] a = new Identifier[] { new Identifier(1, 0), new Identifier(2, 0), new Identifier(3, 0) };
|
||||||
Identifier[] b = new Identifier[] { new Identifier(1, 0), new Identifier(1, 0), new Identifier(3, 0) };
|
Identifier[] b = new Identifier[] { new Identifier(1, 0), new Identifier(1, 0), new Identifier(3, 0) };
|
||||||
assertArrayEquals(Util.subtract(a, b, 0), new int[] { 0, 1, 0 });
|
assertArrayEquals(new int[] { 0, 1, 0 }, Util.subtract(a, b, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCarrySubtraction() {
|
public void testCarrySubtraction() {
|
||||||
Identifier[] a = new Identifier[] { new Identifier(2, 0), new Identifier(0, 0), new Identifier(4, 0) };
|
Identifier[] a = new Identifier[] { new Identifier(2, 0), new Identifier(0, 0), new Identifier(4, 0) };
|
||||||
Identifier[] b = new Identifier[] { new Identifier(1, 0), new Identifier(0, 0), new Identifier(5, 0) };
|
Identifier[] b = new Identifier[] { new Identifier(1, 0), new Identifier(0, 0), new Identifier(5, 0) };
|
||||||
assertArrayEquals(Util.subtract(a, b, 0), new int[] { 0, 9, 9 });
|
assertArrayEquals(new int[] { 0, Util.BASE - 1, Util.BASE - 1 }, Util.subtract(a, b, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOffsetSubtraction() {
|
public void testOffsetSubtraction() {
|
||||||
Identifier[] a = new Identifier[] { new Identifier(1, 0), new Identifier(0, 0), new Identifier(5, 0) };
|
Identifier[] a = new Identifier[] { new Identifier(1, 0), new Identifier(0, 0), new Identifier(5, 0) };
|
||||||
Identifier[] b = new Identifier[] { new Identifier(1, 0), new Identifier(0, 0), new Identifier(4, 0) };
|
Identifier[] b = new Identifier[] { new Identifier(1, 0), new Identifier(0, 0), new Identifier(4, 0) };
|
||||||
assertArrayEquals(Util.subtract(a, b, 1), new int[] { 0, 1 });
|
assertArrayEquals(new int[] { 0, 1 }, Util.subtract(a, b, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReversedInputFails() {
|
||||||
|
Identifier[] a = new Identifier[] { new Identifier(1, 0), new Identifier(1, 0), new Identifier(3, 0) };
|
||||||
|
Identifier[] b = new Identifier[] { new Identifier(1, 0), new Identifier(2, 0), new Identifier(3, 0) };
|
||||||
|
assertThrows(RuntimeException.class, () -> Util.subtract(a, b, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimpleAdd1() {
|
||||||
|
int[] a = new int[] { 0, 0 };
|
||||||
|
Util.add1AtIndex(a, 1);
|
||||||
|
assertArrayEquals(new int[] { 0, 1 }, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCarryAdd1() {
|
||||||
|
int[] a = new int[] { 0, Util.BASE - 1 };
|
||||||
|
Util.add1AtIndex(a, 1);
|
||||||
|
assertArrayEquals(new int[] { 1, 0 }, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCarryAdd1_2() {
|
||||||
|
int[] a = new int[] { 0, Util.BASE - 1, Util.BASE - 1 };
|
||||||
|
Util.add1AtIndex(a, 2);
|
||||||
|
assertArrayEquals(new int[] { 1, 0, 0 }, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCarryAdd1_3() {
|
||||||
|
int[] a = new int[] { 0, Util.BASE - 1, Util.BASE - 1 };
|
||||||
|
Util.add1AtIndex(a, 1);
|
||||||
|
assertArrayEquals(new int[] { 1, 0, Util.BASE - 1 }, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user