ID:168097
 
I have this proc which returns the denominator of a fraction, and I am wondering if it could be made any better. It works for most common fractions, but for some it returns 1.inf/1.inf and for others it does not complete the process. (It returns an integer for the denominator, but it is not the right one, because when this number is multiplied by the original number it creates a fraction, where it should just create an integer.)

proc/getdenominator(n as num)
var/a = abs(frac_part(n))
var/b = 1
while(a>=0.001)
b = b/a
a = frac_part(1/a)
return int_part(b)

proc/int_part(n as num) //This is from Lummox JR
return (n)>=0?round(n):-round(-(n))

proc/frac_part(n as num)
return n - int_part(n)

By using this proc, a decimal can be converted into a fraction by multiplying the original number by the denominator to get the numerator, (number * denominator) / denominator.

You really don't need to do all of that just to get a fraction. You just need to (as you might do in your head) multiply it until the numerator and denominator are both integers.

Here is an example of how you can easily find a fraction of a number.

proc
fraction(number)
var/n = number*100000
var/d = 100000
var/i=2

/*
BYOND's floating point numbers go up to
6 decimal places, so multiply by 100000

n = numerator
d = denominator
i = temporary counting variable
*/


while((i <= n) && (n != 1))
while((n/i == round(n/i)) && (d/i == round(d/i)))
n /= i
d /= i
i++
return "[n]/[!n?1:d]"


~~> Unknown Person
In response to Unknown Person
Although that is an easyer way, It does not allow for repeating numbers such as 1/3. The one i use deoes, as long as you put in enough digits. So maybe I could use both procs.
In response to Drumersl
Maybe you should return the number with num2text() so it doesn't give you 1.#INF.