|
|
@@ -6,6 +6,9 @@
|
|
|
*/
|
|
|
package net.ranides.assira.math;
|
|
|
|
|
|
+import java.util.List;
|
|
|
+import net.ranides.assira.collection.list.VirtualList;
|
|
|
+
|
|
|
/**
|
|
|
* Number represented in "place-value notation" / "positional notation"
|
|
|
* @author ranides
|
|
|
@@ -20,6 +23,16 @@ public abstract class PVNumber extends Number implements Cloneable, Comparable<P
|
|
|
|
|
|
protected static final int DIGITS_DOUBLE = 325;
|
|
|
|
|
|
+ public interface Digit {
|
|
|
+
|
|
|
+ int base();
|
|
|
+
|
|
|
+ int exponent();
|
|
|
+
|
|
|
+ int value();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* base used by number
|
|
|
* @return
|
|
|
@@ -63,7 +76,7 @@ public abstract class PVNumber extends Number implements Cloneable, Comparable<P
|
|
|
* @return
|
|
|
*/
|
|
|
public int size() {
|
|
|
- return end() - begin();
|
|
|
+ return end() - begin() + 1;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@@ -130,18 +143,31 @@ public abstract class PVNumber extends Number implements Cloneable, Comparable<P
|
|
|
}
|
|
|
|
|
|
public String toString(int imax, int fmax) {
|
|
|
- String sep = base()<=10 ? "" : " ";
|
|
|
StringBuilder ret = new StringBuilder();
|
|
|
|
|
|
- for(int i=Math.min(imax-1,end()); i>0; i--) {
|
|
|
- ret.append( get(i) ).append(sep);
|
|
|
- }
|
|
|
- ret.append( get(0) );
|
|
|
- if(begin() < 0) {
|
|
|
- ret.append(sep).append(".");
|
|
|
- }
|
|
|
- for(int i=-1, mi=Math.max(-fmax,begin()); i>=mi; i--) {
|
|
|
- ret.append(sep).append( get(i) );
|
|
|
+ if(base()<=10 || base()==16) {
|
|
|
+ for(int i=Math.min(imax-1,end()); i>0; i--) {
|
|
|
+ ret.append( PVMath.i2c(get(i)) );
|
|
|
+ }
|
|
|
+ ret.append( PVMath.i2c(get(0)) );
|
|
|
+ if(begin() < 0) {
|
|
|
+ ret.append(".");
|
|
|
+ }
|
|
|
+ for(int i=-1, mi=Math.max(-fmax,begin()); i>=mi; i--) {
|
|
|
+ ret.append( PVMath.i2c(get(i)) );
|
|
|
+ }
|
|
|
+ return ret.toString();
|
|
|
+ } else {
|
|
|
+ for(int i=Math.min(imax-1,end()); i>0; i--) {
|
|
|
+ ret.append( get(i) ).append(" ");
|
|
|
+ }
|
|
|
+ ret.append( get(0) );
|
|
|
+ if(begin() < 0) {
|
|
|
+ ret.append(" .");
|
|
|
+ }
|
|
|
+ for(int i=-1, mi=Math.max(-fmax,begin()); i>=mi; i--) {
|
|
|
+ ret.append(" ").append( get(i) );
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return ret.toString();
|
|
|
@@ -184,6 +210,64 @@ public abstract class PVNumber extends Number implements Cloneable, Comparable<P
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Natural ordered list, i.e. most significat digits are before least significant.
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public List<Digit> digits() {
|
|
|
+ return new NDCollection();
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean isZero() {
|
|
|
+ return (0 == begin()) && (0 == end()) && (0 == get(0));
|
|
|
+ }
|
|
|
+
|
|
|
+ private class NDCollection extends VirtualList<Digit> {
|
|
|
+
|
|
|
+ private final int imax;
|
|
|
+ private final int isize;
|
|
|
+
|
|
|
+ public NDCollection() {
|
|
|
+ this.imax = PVNumber.this.end();
|
|
|
+ this.isize = PVNumber.this.size();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int size() {
|
|
|
+ return isize;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Digit get(int index) {
|
|
|
+ return new NDigit(imax - index);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private class NDigit implements Digit {
|
|
|
+
|
|
|
+ private final int exp;
|
|
|
+
|
|
|
+ public NDigit(int exp) {
|
|
|
+ this.exp = exp;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int base() {
|
|
|
+ return PVNumber.this.base();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int exponent() {
|
|
|
+ return exp;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int value() {
|
|
|
+ return PVNumber.this.get(exp);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
|
|
|
}
|