@@ -141,7 +141,20 @@ public struct Rational<T: IntegerNumber>: RationalNumber, CustomStringConvertibl
141141 public init ( _ value: T ) {
142142 self . init ( numerator: value, denominator: T . one)
143143 }
144-
144+
145+ /// Creates a rational number by rationalizing a `Double` value.
146+ public init ( _ value: Double , precision: Double = 1.0e-8 ) {
147+ var x = value
148+ var a = Foundation . floor ( x)
149+ var ( h1, k1, h, k) = ( T . one, T . zero, T ( a) , T . one)
150+ while x - a > precision * k. doubleValue * k. doubleValue {
151+ x = 1.0 / ( x - a)
152+ a = Foundation . floor ( x)
153+ ( h1, k1, h, k) = ( h, k, h1 + T( a) * h, k1 + T( a) * k)
154+ }
155+ self . init ( numerator: h, denominator: k)
156+ }
157+
145158 /// Create an instance initialized to `value`.
146159 public init ( integerLiteral value: Int64 ) {
147160 self . init ( T ( value) )
@@ -341,7 +354,7 @@ extension Rational: ExpressibleByStringLiteral {
341354 /// Compute absolute number of `num` and return a tuple consisting of the result and a
342355 /// boolean indicating whether there was an overflow.
343356 private static func absWithOverflow( _ num: T ) -> ( value: T , overflow: Bool ) {
344- return num < 0 ? T ( 0 ) . subtractingReportingOverflow ( num) : ( num, false )
357+ return num < 0 ? T . zero . subtractingReportingOverflow ( num) : ( num, false )
345358 }
346359
347360 /// Creates a rational number from a numerator and a denominator.
@@ -355,7 +368,7 @@ extension Rational: ExpressibleByStringLiteral {
355368 let ( adenom, overflow2) = Rational . absWithOverflow ( denominator)
356369 let div = Rational . gcd ( anum, adenom)
357370 let ( n, overflow3) = anum. dividedReportingOverflow ( by: div)
358- let ( numer, overflow4) = negative ? T ( 0 ) . subtractingReportingOverflow ( n) : ( n, false )
371+ let ( numer, overflow4) = negative ? T . zero . subtractingReportingOverflow ( n) : ( n, false )
359372 let ( denom, overflow5) = adenom. dividedReportingOverflow ( by: div)
360373 return ( Rational ( numerator: numer, denominator: denom) ,
361374 overflow1 || overflow2 || overflow3 || overflow4 || overflow5)
0 commit comments