@@ -3871,6 +3871,69 @@ define("pyret-base/js/js-numbers", function() {
38713871 return asin ( this . toFixnum ( ) , errbacks ) ;
38723872 } ;
38733873
3874+ //////////////////////////////////////////////////////////////////////
3875+ // getResidue: integer, integer, integer -> [string, string]
3876+ //
3877+ // Given the numerator and denominator of a proper (<= 1) fraction,
3878+ // returns two strings constituting its repeating-decimal representation,
3879+ // where the first string is the non-repeating digits immediately after the
3880+ // decimal point, and the second string is the repeating digits thereafter.
3881+ // The third argument is the limit on the size of the repeating digits.
3882+ // If exceeded, the second string is `...`.
3883+ var getResidue = function ( r , d , limit , errbacks ) {
3884+ var digits = [ ] ;
3885+ var seenRemainders = { } ;
3886+ seenRemainders [ r ] = true ;
3887+ while ( true ) {
3888+ if ( limit -- <= 0 ) {
3889+ return [ digits . join ( '' ) , '...' ]
3890+ }
3891+
3892+ var nextDigit = quotient (
3893+ multiply ( r , 10 , errbacks ) , d , errbacks ) ;
3894+ var nextRemainder = remainder (
3895+ multiply ( r , 10 , errbacks ) ,
3896+ d , errbacks ) ;
3897+ digits . push ( nextDigit . toString ( ) ) ;
3898+ if ( seenRemainders [ nextRemainder ] ) {
3899+ r = nextRemainder ;
3900+ break ;
3901+ } else {
3902+ seenRemainders [ nextRemainder ] = true ;
3903+ r = nextRemainder ;
3904+ }
3905+ }
3906+
3907+ var firstRepeatingRemainder = r ;
3908+ var repeatingDigits = [ ] ;
3909+ while ( true ) {
3910+ var nextDigit = quotient ( multiply ( r , 10 , errbacks ) , d , errbacks ) ;
3911+ var nextRemainder = remainder (
3912+ multiply ( r , 10 , errbacks ) ,
3913+ d , errbacks ) ;
3914+ repeatingDigits . push ( nextDigit . toString ( ) ) ;
3915+ if ( equals ( nextRemainder , firstRepeatingRemainder , errbacks ) ) {
3916+ break ;
3917+ } else {
3918+ r = nextRemainder ;
3919+ }
3920+ } ;
3921+
3922+ var digitString = digits . join ( '' ) ;
3923+ var repeatingDigitString = repeatingDigits . join ( '' ) ;
3924+
3925+ while ( digitString . length >= repeatingDigitString . length &&
3926+ ( digitString . substring (
3927+ digitString . length - repeatingDigitString . length )
3928+ === repeatingDigitString ) ) {
3929+ digitString = digitString . substring (
3930+ 0 , digitString . length - repeatingDigitString . length ) ;
3931+ }
3932+
3933+ return [ digitString , repeatingDigitString ] ;
3934+
3935+ } ;
3936+
38743937 //////////////////////////////////////////////////////////////////////
38753938 // toRepeatingDecimal: jsnum jsnum {limit: number}? -> [string, string, string]
38763939 //
@@ -3880,64 +3943,13 @@ define("pyret-base/js/js-numbers", function() {
38803943 // non-repeating digits after the decimal, and the third are the
38813944 // remaining repeating decimals.
38823945 //
3883- // An optional limit on the decimal expansion can be provided, in which
3884- // case the search cuts off if we go past the limit.
3885- // If this happens, the third argument returned becomes '...' to indicate
3946+ // An optional limit on the decimal expansion can be provided via
3947+ // a `limit` field of an object supplied as a third argument. This
3948+ // cuts off the search if we go past the limit.
3949+ // If this happens, the third string returned becomes '...' to indicate
38863950 // that the search was prematurely cut off.
3951+ // The default limit is 512.
38873952 var toRepeatingDecimal = ( function ( ) {
3888- var getResidue = function ( r , d , limit , errbacks ) {
3889- var digits = [ ] ;
3890- var seenRemainders = { } ;
3891- seenRemainders [ r ] = true ;
3892- while ( true ) {
3893- if ( limit -- <= 0 ) {
3894- return [ digits . join ( '' ) , '...' ]
3895- }
3896-
3897- var nextDigit = quotient (
3898- multiply ( r , 10 , errbacks ) , d , errbacks ) ;
3899- var nextRemainder = remainder (
3900- multiply ( r , 10 , errbacks ) ,
3901- d , errbacks ) ;
3902- digits . push ( nextDigit . toString ( ) ) ;
3903- if ( seenRemainders [ nextRemainder ] ) {
3904- r = nextRemainder ;
3905- break ;
3906- } else {
3907- seenRemainders [ nextRemainder ] = true ;
3908- r = nextRemainder ;
3909- }
3910- }
3911-
3912- var firstRepeatingRemainder = r ;
3913- var repeatingDigits = [ ] ;
3914- while ( true ) {
3915- var nextDigit = quotient ( multiply ( r , 10 , errbacks ) , d , errbacks ) ;
3916- var nextRemainder = remainder (
3917- multiply ( r , 10 , errbacks ) ,
3918- d , errbacks ) ;
3919- repeatingDigits . push ( nextDigit . toString ( ) ) ;
3920- if ( equals ( nextRemainder , firstRepeatingRemainder , errbacks ) ) {
3921- break ;
3922- } else {
3923- r = nextRemainder ;
3924- }
3925- } ;
3926-
3927- var digitString = digits . join ( '' ) ;
3928- var repeatingDigitString = repeatingDigits . join ( '' ) ;
3929-
3930- while ( digitString . length >= repeatingDigitString . length &&
3931- ( digitString . substring (
3932- digitString . length - repeatingDigitString . length )
3933- === repeatingDigitString ) ) {
3934- digitString = digitString . substring (
3935- 0 , digitString . length - repeatingDigitString . length ) ;
3936- }
3937-
3938- return [ digitString , repeatingDigitString ] ;
3939-
3940- } ;
39413953
39423954 return function ( n , d , options , errbacks ) {
39433955 // default limit on decimal expansion; can be overridden
@@ -4099,6 +4111,7 @@ define("pyret-base/js/js-numbers", function() {
40994111 _integerGreaterThanOrEqual : _integerGreaterThanOrEqual ,
41004112 _integerLessThanOrEqual : _integerLessThanOrEqual ,
41014113 splitIntIntoMantissaExpt : splitIntIntoMantissaExpt ,
4114+ getResidue : getResidue ,
41024115 nbi : nbi ,
41034116 integerNthRoot : integerNthRoot ,
41044117 liftFixnumInteger : liftFixnumInteger ,
0 commit comments