I need to detect an infinite quotient. For example, when user divides 1/3, I'm not going to show him 0.333333333333, I'm going show him that result is a repeating decimal.
Here is a possible implementation how to compute the decimal expansion of a fraction and detect repeating decimals (i.e. periods in the decimal expansion). It is a translation of the code posted and reviewed in Decimal expansion of a rational number on Code Review to Swift.
The algorithm is just the Long Division, and an array
(remainders
) is used to check for a periodic decimal expansion.
(For the sake of simplicity, it is assumed that the numerator is
non-negative and the
denominator is positive. This can be generalised if necessary.)
struct DecimalFraction : Printable {
let wholePart : Int // Integer part
let fractionDigits : [Int] // Fractional digits
let repeatingAt : Int? // Position of first repeating digit, or `nil`
// Create DecimalFraction from given fraction
init(numerator : Int, denominator : Int) {
precondition(numerator >= 0, "`numerator` must be non-negative")
precondition(denominator > 0, "`denominator` must be positive")
wholePart = numerator / denominator
var fractionDigits : [Int] = []
var repeatingAt : Int? = nil
var rem = (abs(numerator) % denominator) * 10
var remainders : [Int] = []
while (rem > 0 && repeatingAt == nil) {
remainders.append(rem)
let digit = rem / denominator
rem = (rem % denominator) * 10
fractionDigits.append(digit)
repeatingAt = find(remainders, rem)
}
self.fractionDigits = fractionDigits
self.repeatingAt = repeatingAt
}
// Produce a string description, e.g. "12.3{45}"
var description : String {
var result = String(wholePart) + "."
for (idx, digit) in enumerate(fractionDigits) {
if idx == repeatingAt {
result += "{"
}
result += String(digit)
}
if repeatingAt != nil {
result += "}"
}
return result
}
}
Examples:
println(DecimalFraction(numerator: 3, denominator: 8))
// 0.375
println(DecimalFraction(numerator: 1, denominator: 3))
// 0.{3}
println(DecimalFraction(numerator: 20, denominator: 7))
// 2.{857142}
println(DecimalFraction(numerator: 12222, denominator: 990))
// 12.3{45}
The periods are simply indicated by curly braces, but it should
be easy to modify the code to produce an NSAttributedString
which indicates the periods by – for example – horizontal lines.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With