Convert decimal to fractions in Swift

I am creating a calculator and want it to automatically convert every decimal to a fraction. Therefore, if the user evaluates an expression for which the answer is "0.333333 ...", he returns "1/3". For "0.25" it will return "1/4". Using a GCD, as found here ( Decimal fraction conversion ), I figured out how to convert any rational, terminating decimal number to decimal number, but this does not work on any decimal number that repeats (e.g. .333333).

Every other function for is in Objective-C. But I need a feature in my quick application! So the translated version of this ( https://stackoverflow.com/a/166209/ ... ) will be enjoyable!

Any ideas or solutions on how to convert a rational or repeating / irrational decimal to fractions (i.e. convert “0.1764705882 ...” to 3/17) would be great!

+4
source share
1 answer

100% , .. (numerator, denominator), , , .. .

Double, . ,

let x : Double = 7/10

x 0.7, a Double.

print(String(format:"%a", x)) // 0x1.6666666666666p-1

, x

0x16666666666666 * 2^(-53) = 6305039478318694 / 9007199254740992
                            0.69999999999999995559107901499373838305

, x 6305039478318694 / 9007199254740992, , , , . , , 7/10, :

let x : Double = 69999999999999996/100000000000000000

x, 0.7 Double.

, x 7/10 69999999999999996/100000000000000000?

, . , Double . ( LCM Swift.)

( ) h n/k n, x, Swift:

typealias Rational = (num : Int, den : Int)

func rationalApproximationOf(x0 : Double, withPrecision eps : Double = 1.0E-6) -> Rational {
    var x = x0
    var a = floor(x)
    var (h1, k1, h, k) = (1, 0, Int(a), 1)

    while x - a > eps * Double(k) * Double(k) {
        x = 1.0/(x - a)
        a = floor(x)
        (h1, k1, h, k) = (h, k, h1 + Int(a) * h, k1 + Int(a) * k)
    }
    return (h, k)
}

:

rationalApproximationOf(0.333333) // (1, 3)
rationalApproximationOf(0.25)     // (1, 4)
rationalApproximationOf(0.1764705882) // (3, 17)

- 1.0E-6, :

rationalApproximationOf(0.142857) // (1, 7)
rationalApproximationOf(0.142857, withPrecision: 1.0E-10) // (142857, 1000000)

rationalApproximationOf(M_PI) // (355, 113)
rationalApproximationOf(M_PI, withPrecision: 1.0E-7) // (103993, 33102)
rationalApproximationOf(M_PI, withPrecision: 1.0E-10) // (312689, 99532)

Swift 3:

typealias Rational = (num : Int, den : Int)

func rationalApproximation(of x0 : Double, withPrecision eps : Double = 1.0E-6) -> Rational {
    var x = x0
    var a = x.rounded(.down)
    var (h1, k1, h, k) = (1, 0, Int(a), 1)

    while x - a > eps * Double(k) * Double(k) {
        x = 1.0/(x - a)
        a = x.rounded(.down)
        (h1, k1, h, k) = (h, k, h1 + Int(a) * h, k1 + Int(a) * k)
    }
    return (h, k)
}

:

rationalApproximation(of: 0.333333) // (1, 3)
rationalApproximation(of: 0.142857, withPrecision: 1.0E-10) // (142857, 1000000)
+21

All Articles