@@ -148,7 +148,7 @@ public String getIrrational( int i )
148148 // Eclipse says that rawtypes is unnecessary here, but without it,
149149 // Netbeans and the gradle command line both generate the rawtypes warning
150150 @ SuppressWarnings ({"unchecked" , "rawtypes" })
151- public AbstractAlgebraicField ( String name , int order , AlgebraicNumberFactory factory )
151+ public AbstractAlgebraicField ( String name , int order , AlgebraicNumberFactory factory )
152152 {
153153 this .name = name ;
154154 this .order = order ;
@@ -291,38 +291,35 @@ public final AlgebraicNumber createAlgebraicNumber( int[] terms )
291291 }
292292
293293 /**
294- * Generates an AlgebraicNumber from a "trailing divisor" int array representation.
295- * @param trailingDivisorForm numerators trailed by a common denominator for all numerators
296- * @return
294+ * TODO: BigInteger.longValue() may silently lose precision here.
295+ * That's why it's deprecated.
296+ * I'm going to live with that possibility for now to avoid the overhead
297+ * of calling a BigInt version of convertGoldenNumberPairs().
297298 */
298- @ Override
299- public final AlgebraicNumber createAlgebraicNumberFromTD ( int [] trailingDivisorForm )
299+ @ SuppressWarnings ({ "deprecation" })
300+ public final AlgebraicNumber createAlgebraicNumberFromTD ( BigRational [] trailingDivisorForm )
300301 {
301302 int terms = trailingDivisorForm .length - 1 ;
302- if ( terms == 2 && this .getOrder () > 2 ) {
303-
303+ if ( terms == 2 && this .getOrder () > 2 && this .getGoldenRatio () != null ) {
304304 // Momentarily switch to rational pairs (not reduced), in order to call convertGoldenNumberPairs
305305 // [ a1, a2, d ] => [ a1, d, a2, d, ... aN, d ]
306306 long [] pairs = new long [ 2 *terms ];
307- int divisor = trailingDivisorForm [ terms ];
307+
308+ long divisor = trailingDivisorForm [ terms ].getNumerator () .longValue ();
308309 for (int i = 0 ; i < terms ; i ++) {
309- pairs [ 2 *i + 0 ] = trailingDivisorForm [ i ];
310+ pairs [ 2 *i + 0 ] = trailingDivisorForm [ i ]. getNumerator () . longValue () ;
310311 pairs [ 2 *i + 1 ] = divisor ;
311312 }
312313
314+ // All of this is just so we can call convertGoldenNumberPairs with longs instead of BigIntegers
313315 pairs = this .convertGoldenNumberPairs ( pairs );
314-
315- // Now switch back. Since only zero-valued terms were introduced, we don't need to reduce the fractions.
316- terms = pairs .length /2 ;
317- trailingDivisorForm = new int [ terms + 1 ];
318- trailingDivisorForm [ terms ] = (int ) pairs [ 1 ];
319- for ( int i = 0 ; i < pairs .length /2 ; i ++ ) {
320- trailingDivisorForm [ i ] = (int ) pairs [ 2 *i ];
321- }
316+
317+ return this .numberFactory .createAlgebraicNumberFromPairs ( this , pairs );
322318 }
319+
323320 return this .numberFactory .createAlgebraicNumberFromTD ( this , trailingDivisorForm );
324321 }
325-
322+
326323 /**
327324 * Generates an AlgebraicNumber with the specified numerators,
328325 * all having a common denominator as specified.
@@ -339,14 +336,13 @@ public final AlgebraicNumber createAlgebraicNumber( int[] numerators, int denomi
339336 @ Override
340337 public final AlgebraicNumber createAlgebraicNumber ( int ones , int irrat , int denominator , int scalePower )
341338 {
342- int [] factors = new int [ this .order + 1 ];
339+ int [] factors = new int [ this .order ];
343340 factors [ 0 ] = ones ;
344341 factors [ 1 ] = irrat ;
345- for ( int i = 2 ; i < this . order ; i ++ ) {
342+ for ( int i = 2 ; i < factors . length ; i ++ ) {
346343 factors [ i ] = 0 ;
347344 }
348- factors [ this .order ] = denominator ;
349- AlgebraicNumber result = this .numberFactory .createAlgebraicNumberFromTD ( this , factors );
345+ AlgebraicNumber result = this .numberFactory .createAlgebraicNumber ( this , factors , denominator );
350346 if ( scalePower != 0 ) {
351347 AlgebraicNumber multiplier = this .createPower ( scalePower );
352348 return result .times ( multiplier );
@@ -464,9 +460,14 @@ public final AlgebraicNumber getUnitTerm( int n )
464460 if ( n < 0 ) {
465461 return zero ();
466462 }
467- int [] factors = this .zero () .toTrailingDivisor (); // makes a copy
468- factors [ n ] = factors [ factors .length - 1 ]; // copies the 1n denominator
469- return this .numberFactory .createAlgebraicNumberFromTD ( this , factors );
463+ int [] numerators = new int [getOrder ()];
464+ // Initializing primitive arrays to 0 is automatic in Java,
465+ // but not in JavaScript, so in case the JSweet port needs it...
466+ for (int i = 0 ; i < numerators .length ; i ++) {
467+ numerators [i ] = 0 ;
468+ }
469+ numerators [n ] = 1 ;
470+ return this .numberFactory .createAlgebraicNumber (this , numerators , 1 );
470471 }
471472
472473 /**
@@ -605,21 +606,21 @@ public AlgebraicVector createVector( int[][] nums )
605606 for (int i = 0 ; i < pairs .length ; i ++) {
606607 pairs [ i ] = nums [ c ][ i ];
607608 }
608- if ( pairs .length == 4 && getOrder () > 2 ) {
609+ if ( pairs .length == 4 && getOrder () > 2 && this . getGoldenRatio () != null ) {
609610 pairs = this .convertGoldenNumberPairs ( pairs );
610611 }
611612 coords [c ] = this .numberFactory .createAlgebraicNumberFromPairs ( this , pairs );
612613 }
613614 return new AlgebraicVector ( coords );
614615 }
615616
616- @ Override
617- public AlgebraicVector createVectorFromTDs ( int [][] nums )
617+ // createVectorFromTDs() is only used by ColoredMeshJson and SimpleMeshJson
618+ public AlgebraicVector createVectorFromTDs ( BigRational [][] nums )
618619 {
619620 int dims = nums .length ;
620621 AlgebraicNumber [] coords = new AlgebraicNumber [ dims ];
621622 for (int c = 0 ; c < coords .length ; c ++) {
622- coords [c ] = this .createAlgebraicNumberFromTD ( nums [c ] );
623+ coords [c ] = this .createAlgebraicNumberFromTD ( nums [c ] );
623624 }
624625 return new AlgebraicVector ( coords );
625626 }
@@ -768,11 +769,10 @@ public AlgebraicNumber parseLegacyNumber( String val )
768769 @ Override
769770 public AlgebraicNumber parseVefNumber ( String string , boolean isRational )
770771 {
771- long [] pairs = new long [ this .getOrder () * 2 ];
772- // The pairs array is pre-initialized with zeros since it's a native type (not Integer)
773- // so we can simply set all of the denominators to 1.
774- for ( int i = 1 ; i < pairs .length ; i +=2 ) {
775- pairs [ i ] = 1 ;
772+ String [] fractions = new String [ this .getOrder () ];
773+ // initialize all pairs to "0/1", in case the string provides fewer factors than the field order
774+ for ( int i = 0 ; i < this .getOrder (); i ++ ) {
775+ fractions [ i ] = "0/1" ;
776776 }
777777 // if the field is declared as rational, then we won't allow the irrational syntax using parenthesis
778778 // if the field is NOT declared as rational, then we will still allow the rational format as shorthand with no parenthesis
@@ -788,33 +788,40 @@ public AlgebraicNumber parseVefNumber( String string, boolean isRational )
788788 // With an order 6 field, if only 2 factors are provided, "(3,-2)" must still be parsed into a 6 element array as {-2, 3, 0, 0, 0, 0}
789789 // Since VEF version 7 no longer requires that all factors be provided, we need to push the factors onto a stack
790790 // and pop them off to reverse the order as they are inserted into the begining of the factors array.
791- Stack <Integer > numStack = new Stack <>();
792- Stack <Integer > denomStack = new Stack <>();
791+ Stack <String > numStack = new Stack <>();
792+ Stack <String > denomStack = new Stack <>();
793793 while ( tokens .hasMoreTokens () ) {
794794 if ( numStack .size () >= this .getOrder () ) {
795795 throw new RuntimeException ( "VEF format error: \" " + string + "\" has too many factors for " + this .getName () + " field" );
796796 }
797797 String [] parts = tokens .nextToken () .split ( "/" );
798- numStack .push ( Integer . parseInt ( parts [ 0 ] ) );
799- denomStack .push ( (parts .length > 1 )? Integer . parseInt ( parts [ 1 ] ) : 1 );
798+ numStack .push ( parts [ 0 ] );
799+ denomStack .push ( (parts .length > 1 )? parts [ 1 ] : "1" );
800800 }
801801 int i = 0 ;
802802 while ( ! numStack .empty () ) {
803- pairs [ i ++ ] = numStack .pop ();
804- pairs [ i ++ ] = denomStack .pop ();
803+ fractions [ i ++ ] = numStack .pop () + "/" + denomStack .pop ();
805804 }
806- if ( i == 4 && getOrder () > 2 ) {
805+ if ( i == 2 && getOrder () > 2 && this .getGoldenRatio () != null ) {
806+ String [][] fractionParts = new String [][] {
807+ fractions [0 ] .split ( "/" ),
808+ fractions [1 ] .split ( "/" )
809+ };
810+ long [] pairs = new long [] {
811+ Long .parseLong ( fractionParts [0 ][0 ] ), Long .parseLong ( fractionParts [0 ][1 ] ),
812+ Long .parseLong ( fractionParts [1 ][0 ] ), Long .parseLong ( fractionParts [1 ][1 ] )
813+ };
807814 pairs = this .convertGoldenNumberPairs ( new long [] { pairs [0 ], pairs [1 ], pairs [2 ], pairs [3 ] } );
815+ return this .numberFactory .createAlgebraicNumberFromPairs ( this , pairs );
808816 }
809817 }
810818 else {
811819 // format >= 7 supports the rational numeric format which expects no irrational factors,
812820 // so there are no parentheses or commas, but still allows the optional "/" if a denominator is specified.
813821 String [] parts = string .split ( "/" );
814- pairs [ 0 ] = Integer .parseInt ( parts [ 0 ] );
815- pairs [ 1 ] = (parts .length > 1 )? Integer .parseInt ( parts [ 1 ] ) : 1 ;
822+ fractions [ 0 ] = parts [ 0 ] + "/" + ((parts .length > 1 )? parts [ 1 ] : "1" );
816823 }
817- return this . numberFactory . createAlgebraicNumberFromPairs ( this , pairs );
824+ return this . parseNumber ( String . join ( " " , fractions ) );
818825 }
819826
820827 @ Override
@@ -832,17 +839,12 @@ public AlgebraicNumber parseNumber( String nums )
832839 private AlgebraicNumber parseNumber ( StringTokenizer tokens )
833840 {
834841 int order = this .getOrder ();
835- long [] pairs = new long [ order * 2 ];
842+ BigRational [] bigs = new BigRational [ order ];
836843 for ( int i = 0 ; i < order ; i ++ ) {
837844 String digit = tokens .nextToken ();
838- String [] parts = digit .split ( "/" );
839- pairs [ i * 2 ] = Long .parseLong ( parts [ 0 ] );
840- if ( parts .length > 1 )
841- pairs [ i * 2 + 1 ] = Long .parseLong ( parts [ 1 ] );
842- else
843- pairs [ i * 2 + 1 ] = 1 ;
845+ bigs [ i ] = this .numberFactory .parseBigRational ( digit );
844846 }
845- return this .numberFactory .createAlgebraicNumberFromPairs ( this , pairs );
847+ return this .numberFactory .createAlgebraicNumberFromBRs ( this , bigs );
846848 }
847849
848850 @ Override
0 commit comments