@@ -900,32 +900,36 @@ func floatToFraction(x float64, numeratorPlaceHolder, denominatorPlaceHolder int
900900
901901// floatToFracUseContinuedFraction implement convert a floating-point decimal
902902// to a fraction using continued fractions and recurrence relations.
903- func floatToFracUseContinuedFraction (x float64 , denominatorLimit int64 ) (num , den int64 ) {
904- p_1 := int64 (1 )
905- q_1 := int64 (0 )
906- p_2 := int64 (0 )
907- q_2 := int64 (1 )
903+ // Formula reference: https://en.wikipedia.org/wiki/Continued_fraction#Fundamental_recurrence_formulas
904+ // or https://oi-wiki.org/math/number-theory/continued-fraction/#%E9%80%92%E6%8E%A8%E5%85%B3%E7%B3%BB
905+ func floatToFracUseContinuedFraction (r float64 , denominatorLimit int64 ) (num , den int64 ) {
906+ p_1 := int64 (1 ) // LaTex: p_{-1}
907+ q_1 := int64 (0 ) // LaTex: q_{-1}
908+ p_2 := int64 (0 ) // LaTex: p_{-2}
909+ q_2 := int64 (1 ) // LaTex: q_{-2}
908910 var lasta , lastb int64
909911 var curra , currb int64
910- for i := 0 ; i < 100 ; i ++ {
911- a := int64 (math .Floor (x ))
912+ for k := 0 ; ; k ++ {
913+ // a_{k} = \lfloor r_{k} \rfloor
914+ a := int64 (math .Floor (r ))
915+ // Fundamental recurrence formulas: p_{k} = a_{k} \cdot p_{k-1} + p_{k-2}
912916 curra , currb = a * p_1 + p_2 , a * q_1 + q_2
913917 p_2 = p_1
914918 q_2 = q_1
915919 p_1 = curra
916920 q_1 = currb
917- frac := x - float64 (a )
921+ frac := r - float64 (a )
918922 if q_1 >= denominatorLimit {
919- return lasta , lastb //big.NewRat(lasta, lastb)
923+ return lasta , lastb
920924 }
921925 if math .Abs (frac ) < 1e-12 {
922- return curra , currb //big.NewRat(curra, currb)
926+ // use safe floating-point number comparison. If the input(r) is a real number, here is 0.
927+ return curra , currb
923928 }
924-
925929 lasta , lastb = curra , currb
926- x = 1.0 / frac
930+ // r_{k+1} = \frac{1}{r_{k} - a_{k}}
931+ r = 1.0 / frac
927932 }
928- return lasta , lastb //big.NewRat(lasta, lastb)
929933}
930934
931935// assignFieldValue assigns the value from an immutable reflect.Value to a
0 commit comments