How to convert float to fraction in Swift [duplicate] - swift

I am building a calculator and want it to automatically convert every decimal into a fraction. So if the user calculates an expression for which the answer is "0.333333...", it would return "1/3". For "0.25" it would return "1/4". Using GCD, as found here (Decimal to fraction conversion), I have figured out how to convert any rational, terminating decimal into a decimal, but this does not work on any decimal that repeats (like .333333).
Every other function for this on stack overflow is in Objective-C. But I need a function in my swift app! So a translated version of this (https://stackoverflow.com/a/13430237/5700898) would be nice!
Any ideas or solutions on how to convert a rational or repeating/irrational decimal to a fraction (i.e. convert "0.1764705882..." to 3/17) would be great!

If you want to display the results of calculations as rational numbers
then the only 100% correct solution is to use rational arithmetic throughout all calculations, i.e. all intermediate values are stored as a pair of integers (numerator, denominator), and all additions, multiplications, divisions, etc are done using the rules for rational
numbers.
As soon as a result is assigned to a binary floating point number
such as Double, information is lost. For example,
let x : Double = 7/10
stores in x an approximation of 0.7, because that number cannot
be represented exactly as a Double. From
print(String(format:"%a", x)) // 0x1.6666666666666p-1
one can see that x holds the value
0x16666666666666 * 2^(-53) = 6305039478318694 / 9007199254740992
≈ 0.69999999999999995559107901499373838305
So a correct representation of x as a rational number would be
6305039478318694 / 9007199254740992, but that is of course not what
you expect. What you expect is 7/10, but there is another problem:
let x : Double = 69999999999999996/100000000000000000
assigns exactly the same value to x, it is indistinguishable from
0.7 within the precision of a Double.
So should x be displayed as 7/10 or as 69999999999999996/100000000000000000 ?
As said above, using rational arithmetic would be the perfect solution.
If that is not viable, then you can convert the Double back to
a rational number with a given precision.
(The following is taken from Algorithm for LCM of doubles in Swift.)
Continued Fractions
are an efficient method to create a (finite or infinite) sequence of fractions hn/kn that are arbitrary good approximations to a given real number x,
and here is a possible implementation in 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)
}
Examples:
rationalApproximationOf(0.333333) // (1, 3)
rationalApproximationOf(0.25) // (1, 4)
rationalApproximationOf(0.1764705882) // (3, 17)
The default precision is 1.0E-6, but you can adjust that to your needs:
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 version:
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)
}
Examples:
rationalApproximation(of: 0.333333) // (1, 3)
rationalApproximation(of: 0.142857, withPrecision: 1.0E-10) // (142857, 1000000)
Or – as suggested by #brandonscript – with a struct Rational and an initializer:
struct Rational {
let numerator : Int
let denominator: Int
init(numerator: Int, denominator: Int) {
self.numerator = numerator
self.denominator = denominator
}
init(approximating x0: Double, withPrecision eps: Double = 1.0E-6) {
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)
}
self.init(numerator: h, denominator: k)
}
}
Example usage:
print(Rational(approximating: 0.333333))
// Rational(numerator: 1, denominator: 3)
print(Rational(approximating: .pi, withPrecision: 1.0E-7))
// Rational(numerator: 103993, denominator: 33102)

So a little late here, but I had a similar problem and ended up building Swift FractionFormatter. This works because most of the irrational numbers you care about are part of the set of vulgar, or common fractions and are easy to validate proper transformation. The rest may or may not round, but you get very close on any reasonable fraction your user might generate. It is designed to be a drop in replacement for NumberFormatter.

As Martin R said, the Only way to have (99.99%)exact calculations, is to calculate everything with rational numbers, from beginning to the end.
the reason behind the creation of this class was also the fact that i needed to have very accurate calculations, and that was not possible with the swift-provided types. so i created my own type.
here is the code, i'll explain it below.
class Rational {
var alpha = 0
var beta = 0
init(_ a: Int, _ b: Int) {
if (a > 0 && b > 0) || (a < 0 && b < 0) {
simplifier(a,b,"+")
}
else {
simplifier(a,b,"-")
}
}
init(_ double: Double, accuracy: Int = -1) {
exponent(double, accuracy)
}
func exponent(_ double: Double, _ accuracy: Int) {
//Converts a double to a rational number, in which the denominator is of power of 10.
var exp = 1
var double = double
if accuracy != -1 {
double = Double(NSString(format: "%.\(accuracy)f" as NSString, double) as String)!
}
while (double*Double(exp)).remainder(dividingBy: 1) != 0 {
exp *= 10
}
if double > 0 {
simplifier(Int(double*Double(exp)), exp, "+")
}
else {
simplifier(Int(double*Double(exp)), exp, "-")
}
}
func gcd(_ alpha: Int, _ beta: Int) -> Int {
// Calculates 'Greatest Common Divisor'
var inti: [Int] = []
var multi = 1
var a = Swift.min(alpha,beta)
var b = Swift.max(alpha,beta)
for idx in 2...a {
if idx != 1 {
while (a%idx == 0 && b%idx == 0) {
a = a/idx
b = b/idx
inti.append(idx)
}
}
}
inti.map{ multi *= $0 }
return multi
}
func simplifier(_ alpha: Int, _ beta: Int, _ posOrNeg: String) {
//Simplifies nominator and denominator (alpha and beta) so they are 'prime' to one another.
let alpha = alpha > 0 ? alpha : -alpha
let beta = beta > 0 ? beta : -beta
let greatestCommonDivisor = gcd(alpha,beta)
self.alpha = posOrNeg == "+" ? alpha/greatestCommonDivisor : -alpha/greatestCommonDivisor
self.beta = beta/greatestCommonDivisor
}
}
typealias Rnl = Rational
func *(a: Rational, b: Rational) -> Rational {
let aa = a.alpha*b.alpha
let bb = a.beta*b.beta
return Rational(aa, bb)
}
func /(a: Rational, b: Rational) -> Rational {
let aa = a.alpha*b.beta
let bb = a.beta*b.alpha
return Rational(aa, bb)
}
func +(a: Rational, b: Rational) -> Rational {
let aa = a.alpha*b.beta + a.beta*b.alpha
let bb = a.beta*b.beta
return Rational(aa, bb)
}
func -(a: Rational, b: Rational) -> Rational {
let aa = a.alpha*b.beta - a.beta*b.alpha
let bb = a.beta*b.beta
return Rational(aa, bb)
}
extension Rational {
func value() -> Double {
return Double(self.alpha) / Double(self.beta)
}
}
extension Rational {
func rnlValue() -> String {
if self.beta == 1 {
return "\(self.alpha)"
}
else if self.alpha == 0 {
return "0"
}
else {
return "\(self.alpha) / \(self.beta)"
}
}
}
// examples:
let first = Rnl(120,45)
let second = Rnl(36,88)
let third = Rnl(2.33435, accuracy: 2)
let forth = Rnl(2.33435)
print(first.alpha, first.beta, first.value(), first.rnlValue()) // prints 8 3 2.6666666666666665 8 / 3
print((first*second).rnlValue()) // prints 12 / 11
print((first+second).rnlValue()) // prints 203 / 66
print(third.value(), forth.value()) // prints 2.33 2.33435
First of all, we have the class itself. the class can be initialised in two ways:
in the Rational class, alpha ~= nominator & beta ~= denominator
The First way is initialising the class using two integers, first of with is the nominator, and the second one is the denominator. the class gets those two integers, and then reduces them to the least numbers possible. e.g reduces (10,5) to (2,1) or as another example, reduces (144, 60) to (12,5). this way, always the simplest numbers are stored.
this is possible using the gcd (greatest common divisor) function and simplifier function, which are not hard to understand from the code.
the only thing is that the class faces some issues with negative numbers, so it always saves whether the final rational number is negative or positive, and if its negative it makes the nominator negative.
The Second way to initialise the class, is with a double, and with an optional parameter called 'accuracy'. the class gets the double, and also the accuracy of how much numbers after decimal point you need, and converts the double to a nominator/denominator form, in which the denominator is of power of 10. e.g 2.334 will be 2334/1000 or 342.57 will be 34257/100. then tries to simplify the rational numbers using the same method which was explained in the #1 way.
After the class definition, there is type-alias 'Rnl', which you can obviously change it as you wish.
Then there are 4 functions, for the 4 main actions of math: * / + -, which i defined so e.g. you can easily multiply two numbers of type Rational.
After that, there are 2 extensions to Rational type, first of which ('value') gives you the double value of a Rational number, the second one ('rnlValue') gives you the the Rational number in form of a human-readable string: "nominator / denominator"
At last, you can see some examples of how all these work.

Related

swift - (n C k) and (n P k) - calculating binomial coefficient? [duplicate]

This question already has answers here:
Calculate all permutations of a string in Swift
(10 answers)
Closed last month.
This post was edited and submitted for review last month and failed to reopen the post:
Original close reason(s) were not resolved
note: stack overflow incorrectly marked this as duplicate after an answer (there is no built in) was already selected...linked question unrelated
What is the simplest built-in way to calculate num. combinations/permutations in Swift? Official Apple library?
(n C k)
python3.8:
math.comb(n,k)
(n P k)
python3.8:
math.perm(n,k)
Swift does not provide built-in functions for permutation, combination, or even factorial. But these simple formulas are easy to implement.
Here is a trivial factorial function:
func factorial(_ n: Int) -> Int {
return (1...n).reduce(1, { $0 * $1 })
}
But note that this will crash where n >= 21 since 21! is too large to fit in an Int variable.
Here is a naive implementation of "perm":
func perm(n: Int, k: Int) -> Int {
return factorial(n) / factorial(n - k)
}
And for "comb" you can do:
func comb(n: Int, k: Int) -> Int {
return perm(n: n, k: k) / factorial(k)
}
However, there is a simple improvement to be made for "perm". Let's say n = 5 and k = 2. You can write the formula for perm as:
n! = 5! = 5! = 1 * 2 * 3 * 4 * 5
------ ------ -- ----------------- = 4 * 5
(n-k)! = (5-2)! = 3! = 1 * 2 * 3
This boils down to "perm" being equal to (n-k+1) * (n-k+2) * ... n
So let's rewrite the functions to be more efficient:
func mult(_ range: ClosedRange<Int>) -> Int {
return range.reduce(1, { $0 * $1 })
}
func perm(n: Int, k: Int) -> Int {
return mult((n - k + 1)...n)
}
func comb(n : Int, k: Int) -> Int {
return perm(n: n, k: k) / mult(1...k)
}
Note that the "comb" function didn't actually change other than to use mult(1...k) instead of factorial(k) which both give the same result.
These functions still have limits on the sizes of n and k before they will crash due to the limits on the Int data type.

How to ceil the result for UInt division in Chisel

As the title stated, how to do that?
val a = 3.U
val result = a / 2.U
result would be 1.U
However I want to apply ceil on division.
val result = ceil(a / 2.U )
Therefore, I could get 2.U of the result value.
When dividing a by b, if you know that a is not too big (namely that a <= UInt.MaxValue - (b - 1)), then you can do
def ceilUIntDiv(a: UInt, b: UInt): UInt =
(a + b - 1.U) / b
If a is potentially too big, then the above can overflow, and you'll need to adapt the result after the fact instead:
def ceilUIntDiv(a: UInt, b: UInt): UInt = {
val c = a / b
if (b * c == a) c else c + 1.U
}
The problem is the expression a / 2.U is indeed 1.U: if you apply ceil to 1.U you'll get 1.U.
Recall that this happens to Ints as well, as they use integer division:
scala> val result = Math.ceil(3 / 2)
result: Double = 1.0
What you should do is to enforce one of the division operands to be a Double likewise:
scala> val result = Math.ceil(3 / (2: Double))
result: Double = 2.0
And then just convert it back to UInt.
def ceilUIntDiv(a: UInt, b: UInt): UInt = {
(a / b) + {if (a % b == 0.U) 0.U else 1.U}
}

Make Int round off to nearest value

I've got two Int values (they have to be Ints) and I want them to round off to the nearest value when in an equation;
var Example = Int()
var secondExample = Int()
Example = (secondExample / 7000)
This equation makes the variable Example always round down to the lowest value. Say for example that the numbers are the following;
var Example = Int()
var secondExample : Int = 20000
Example = (20000 / 7000)
20000 / 7000 equals 2.857... But the variable Example displays 2.
How can I make Example round off to closest number without changing it to a Double
For nonnegative integers, the following function gives
the desired result in pure integer arithmetic :
func divideAndRound(numerator: Int, _ denominator: Int) -> Int {
return (2 * numerator + denominator)/(2 * denominator)
}
Examples:
print(20000.0/7000.0) // 2.85714285714286
print(divideAndRound(20000, 7000)) // 3 (rounded up)
print(10000.0/7000.0) // 1.42857142857143
print(divideAndRound(10000, 7000)) // 1 (rounded down)
The idea is that
a 1 2 * a + b
- + - = ---------
b 2 2 * b
And here is a possible implementation for arbitrarily signed
integers which also does not overflow:
func divideAndRound(num: Int, _ den: Int) -> Int {
return num / den + (num % den) / (den / 2 + den % 2)
}
(Based on #user3441734's updated solution, so we have a reference
cycle between our answers now :)
There is also a ldiv function which computes both quotient
and remainder of a division, so the last function could also be
implemented as
func divideAndRound(num: Int, _ den: Int) -> Int {
let div = ldiv(num, den)
let div2 = ldiv(den, 2)
return div.quot + div.rem / (div2.quot + div2.rem)
}
(I did not test which version is faster.)
see Martin's answer! his idea is great, so i extend his solution for negative numbers
func divideAndRound(n: Int, _ d: Int) -> Int {
let sn = n < 0 ? -1 : 1
let sd = d < 0 ? -1 : 1
let s = sn * sd
let n = n * sn
let d = d * sd
return (2 * n + d)/(2 * d) * s
}
divideAndRound(1, 2) // 1
divideAndRound(1, 3) // 0
divideAndRound(-1, 2) // -1
divideAndRound(-1, 3) // 0
divideAndRound(1, -2) // -1
divideAndRound(1, -3) // 0
the only trouble is that (2 * n + d) can overflow and code will crash.
UPDATE! with help of mathematics for children
func divr(a: Int, _ b: Int)->Int {
return (a % b) * 2 / b + a / b
}
it should work for any Int :-) except 0 denominator.

How to find the nth root of a value?

In Swift, what would the easiest way to find the nth root of a value be?
We know that the Nth root of a number, x, is equivalent of raising x to a power that is the reciprocal of N. Knowing this, we can use the pow function to find the Nth root:
let nthRoot = pow(base, (1/n))
where base and n are floating point variables.
let nthRoot = pow(base, (1/n)) // will return nan for negative base
This expression is a partial solution, because it will not work for negative base numbers.
Ex. The cubic root to -27 is well defined(-3) by all math laws.
Here is a function that calculates the nth-root properly for negative values, where value is the number which will be rooted by n:
func nthroot(value: Double, _ n: Double) -> Double {
var res: Double
if (value < 0 && abs(n % 2) == 1) {
res = -pow(-value, 1/n)
} else {
res = pow(value, 1/n)
}
return res
}
nthroot(-27, 3) // returns -3
And the same function using ternary operator:
func nthroot(value: Double, _ n: Double) -> Double {
return value < 0 && abs(n % 2) == 1 ? -pow(-value, 1/n) : pow(value, 1/n)
}
nthroot(-27, 3) // also returns -3

Exponentiation operator in Swift

I don't see an exponentiation operator defined in the base arithmetic operators in the Swift language reference.
Is there really no predefined integer or float exponentiation operator in the language?
There isn't an operator but you can use the pow function like this:
return pow(num, power)
If you want to, you could also make an operator call the pow function like this:
infix operator ** { associativity left precedence 170 }
func ** (num: Double, power: Double) -> Double{
return pow(num, power)
}
2.0**2.0 //4.0
If you happen to be raising 2 to some power, you can use the bitwise left shift operator:
let x = 2 << 0 // 2
let y = 2 << 1 // 4
let z = 2 << 7 // 256
Notice that the 'power' value is 1 less than you might think.
Note that this is faster than pow(2.0, 8.0) and lets you avoid having to use doubles.
For anyone looking for a Swift 3 version of the ** infix operator:
precedencegroup ExponentiationPrecedence {
associativity: right
higherThan: MultiplicationPrecedence
}
infix operator ** : ExponentiationPrecedence
func ** (_ base: Double, _ exp: Double) -> Double {
return pow(base, exp)
}
func ** (_ base: Float, _ exp: Float) -> Float {
return pow(base, exp)
}
2.0 ** 3.0 ** 2.0 // 512
(2.0 ** 3.0) ** 2.0 // 64
Swift 4.2
import Foundation
var n = 2.0 // decimal
var result = 5 * pow(n, 2)
print(result)
// 20.0
I did it like so:
operator infix ** { associativity left precedence 200 }
func ** (base: Double, power: Double) -> Double {
return exp(log(base) * power)
}
There isn't one but you have the pow function.
Like most of the C-family of languages, there isn't one.
If you're specifically interested in the exponentiation operator for Int type, I don't think that existing answers would work particularly well for large numbers due to the way how floating point numbers are represented in memory. When converting to Float or Double from Int and then back (which is required by pow, powf and powl functions in Darwin module) you may lose precision. Here's a precise version for Int:
let pow = { Array(repeating: $0, count: $1).reduce(1, *) }
Note that this version isn't particularly memory efficient and is optimized for source code size.
Another version that won't create an intermediate array:
func pow(_ x: Int, _ y: Int) -> Int {
var result = 1
for i in 0..<y {
result *= x
}
return result
}
An alternative answer is to use NSExpression
let mathExpression = NSExpression(format:"2.5**2.5")
let answer = mathExpression.expressionValue(with: nil, context: nil) as? Double
or
let mathExpression = NSExpression(format:"2**3")
let answer = mathExpression.expressionValue(with: nil, context: nil) as? Int
This answer provides a tested and optimized* function for calculating integer powers of integers, while also providing several versions of the custom ** operators for exponentiation.
* At least I think it’s optimized, based on what I read on this page.
My guess is that Swift deliberately does not provide this because of the need to choose what to do about results that have absolute values of less than 1. Do you want it to round to 0 or implicitly cast to a decimal type? The compiler can’t know, and choosing a default may lead to people using it without realizing what mathematical choice they just made.
In Swift 5.3:
import Foundation
precedencegroup ExponeniationPrecedence {
associativity: right // This makes Towers of Powers work correctly
higherThan: MultiplicationPrecedence
}
infix operator ** : ExponeniationPrecedence
public func **(_ base: Int, _ exponent: Int) -> Int {
return pow(base, exponent)
}
public func **(_ base: Double, _ exponent: Double) -> Double {
return pow(base, exponent)
}
public func **(_ base: Decimal, _ exponent: Int) -> Decimal {
return pow(base, exponent)
}
public func **(_ base: Float, _ exponent: Float) -> Float {
return powf(base, exponent)
}
/// Calculate exponentiation of integer base and integer exponent, returning integer result.
///
/// Exponentiation that would result in absolute values of less than 1 (i.e. exponent is negative and base is not 1 or -1) are rounded 0.
public func pow(_ base: Int, _ exponent: Int) -> Int {
// Optimize cases for certain exponents
switch exponent {
case 0:
return 1
case 1:
return base
case _ where exponent < 0 && base != -1 && base != 1:
// Negative exponents of integers always round to zero, except if the base is 1 or -1
return 0
default:
break
}
// Optimize cases for certain bases
switch base {
case -1:
if exponent % 2 == 0 {
return -1 * base
} else {
return base
}
case 0, 1:
return base
case -2, 2:
// Use the bitwise left shift operator to efficiently calculate powers of 2 and -2
let result = 1 << exponent
if base == -2 && exponent % 2 == 1 {
return -1 * result
}
return result
default:
var result = 1
for i in 1 ... exponent {
result *= base
}
return result
}
}
/// Calculate powers of integer base and integer exponent using Foundation's pow function by casting both the base and the exponent as Doubles, calling pow, but without casting the result.
/// Useful if rounding results between -1 and 1 to zero is not acceptable.
public func pow(_ base: Int, _ exponent: Int) -> Double {
return pow(Double(base), Double(exponent))
}
/// Calculate powers of integer base and integer exponent using Foundation's pow function by casting both the base and the exponent as Doubles, calling pow, and then casting the result as an Int
/// If results are -1<x<1, round to 0.
public func castPow(_ base: Int, _ exponent: Int) -> Int {
return Int(pow(base, exponent))
}
Test cases for the pow(Int, Int) function:
// Test Exponent = 0
assert(0**0 == 1)
assert(1**0 == 1)
assert(2**0 == 1)
// Test Exponent = 1
assert(-1**1 == -1)
assert(0**1 == 0)
assert(1**1 == 1)
assert(2**1 == 2)
// Test Exponent = -1
assert(-1 ** -1 == -1)
assert(0 ** -1 == 0)
assert(1 ** -1 == 1)
assert(2 ** -1 == 0)
// Test Exponent = 2
assert(-1 ** 2 == 1)
assert(0 ** 2 == 0)
assert(1 ** 2 == 1)
assert(2 ** 2 == 4)
assert(3 ** 2 == 9)
// Test Base = 0
assert(0**0 == 1)
assert(0**1 == 0)
assert(0**2 == 0)
// Test Base = 1
assert(1 ** -1 == 1)
assert(1**0 == 1)
assert(1**1 == 1)
assert(1**2 == 1)
// Test Base = -1
assert(-1 ** -1 == -1)
assert(-1**0 == 1)
assert(-1**1 == -1)
assert(-1**2 == 1)
assert(-1**2 == 1)
assert(-1**3 == -1)
// Test Base = 2
assert(2 ** -1 == 0)
assert(2**0 == 1)
assert(2**1 == 2)
assert(2**2 == 4)
assert(2**3 == 8)
// Test Base = -2
assert(-2 ** -1 == 0)
assert(-2**0 == 1)
assert(-2**1 == -2)
assert(-2**2 == 4)
assert(-2**3 == -8)
// Test Base = 3
assert(3 ** -1 == 0)
assert(3**0 == 1)
assert(3**1 == 3)
assert(3**2 == 9)
assert(3**3 == 27)
// Test Towers of Powers
assert(2**2**2 == 16)
assert(3**2**2 == 81)
assert(2**2**3 == 256)
assert(2**3**2 == 512)