i am working on a calculator running in pure lua but i need help with making the out put decimals in to fractions
Asked
Active
Viewed 1,600 times
0
-
What have you tried so far? As a first step, I suggest deciding how many decimal places to represent in your fraction. – luther Apr 23 '17 at 00:07
-
1Give an example of desired input and output. – lhf Apr 23 '17 at 01:31
2 Answers
2
This solution uses continued fraction to exactly restore fractions with denominator up to 107
local function to_frac(num)
local W = math.floor(num)
local F = num - W
local pn, n, N = 0, 1
local pd, d, D = 1, 0
local x, err, q, Q
repeat
x = x and 1 / (x - q) or F
q, Q = math.floor(x), math.floor(x + 0.5)
pn, n, N = n, q*n + pn, Q*n + pn
pd, d, D = d, q*d + pd, Q*d + pd
err = F - N/D
until math.abs(err) < 1e-15
return N + D*W, D, err
end
local function print_frac(numer,denom)
print(string.format("%.14g/%d = %d/%d + %g", numer, denom, to_frac(numer/denom)))
end
print_frac(1, 4) --> 1/4 = 1/4 + 0
print_frac(12, 8) --> 12/8 = 3/2 + 0
print_frac(4, 2) --> 4/2 = 2/1 + 0
print_frac(16, 11) --> 16/11 = 16/11 + 5.55112e-17
print_frac(1, 13) --> 1/13 = 1/13 + 0
print_frac(math.sqrt(3), 1) --> 1.7320508075689/1 = 50843527/29354524 + -4.44089e-16
print_frac(math.pi, 1) --> 3.1415926535898/1 = 80143857/25510582 + 4.44089e-16
print_frac(0, 3) --> 0/3 = 0/1 + 0
print_frac(-10, 3) --> -10/3 = -10/3 + -1.11022e-16

Egor Skriptunoff
- 23,359
- 2
- 34
- 64
1
This is not possible. You need a class which stores fractions for that.
You can achieve an approximate solution. It works nicely for things that can be expressed as fraction and blows up for everything else
local function gcd(a, b)
while a ~= 0 do
a, b = b%a, a;
end
return b;
end
local function round(a)
return math.floor(a+.5)
end
function to_frac(num)
local integer = math.floor(num)
local decimal = num - integer
if decimal == 0 then
return num, 1.0, 0.0
end
local prec = 1000000000
local gcd_ = gcd(round(decimal*prec), prec)
local numer = math.floor((integer*prec + round(decimal*prec))/gcd_)
local denom = math.floor(prec/gcd_)
local err = numer/denom - num
return numer, denom, err
end
function print_frac(numer,denom)
print(string.format("%d/%d = %d/%d + %g", numer, denom, to_frac(numer/denom)))
end
print_frac(1,4)
print_frac(12,8)
print_frac(4,2)
print_frac(16,11)
print_frac(1,13)
Output:
1/4 = 1/4 + 0
12/8 = 3/2 + 0
4/2 = 2/1 + 0
16/11 = 290909091/200000000 + 4.54546e-10
1/13 = 76923077/1000000000 + 7.69231e-11

Community
- 1
- 1

Henri Menke
- 10,705
- 1
- 24
- 42