Jump to content

Archived

This topic is now archived and is closed to further replies.

ghgarcia

convert integer to fraction

Recommended Posts

I have a situation where I would like to take a value from my database which in float with 1 decimal point and display it as a fraction i.e. 6.5 would display 61/2 using the fraction symbol.

Any help would be greatly appreciated.

George

Share this post


Link to post
Share on other sites
It's not pretty, but it works:

[code]$fractions= array();

for ($i = 1; $i < 1000; $i++) {
$v = 1 / $i;
$fractions['1/' . $i] = $v;
}

$a = array(6.5, 7.25, 1.125);

foreach ($a as $num) {
$num = explode(".",$num);

foreach ($fractions as $key => $value) {
if ($value == "." . $num[1]) {
echo implode(".",$num) . " = " . $num[0] . " " . $key . "<br>";
}
}
}[/code]

Share this post


Link to post
Share on other sites
try[code]
<?php
function flo_to_fract($a){
if ($a==0) return '0';
$a1=floor($a);
if ($a1==0) $a1=''; else $a1 ="$a1 ";
$b=$a-$a1;
$c=strlen("$b")-2;
$c=round("1E+$c");
$b=round($b * $c);
if ($b==0) return $a1;
while (($b%2)==0) {
$b=$b/2;
$c=$c/2;
}
while (($b%5)==0) {
$b=$b/5;
$c=$c/5;
}
$a1.="$b/$c";
return $a1;
}
echo flo_to_fract(7.125);
?>
[/code]

Share this post


Link to post
Share on other sites
@sasa,

I'm playing devil's advocate again. Try

echo flo_to_fract(7.625);

Share this post


Link to post
Share on other sites
this is a very brutish method, but i don't have the concentration to really make a more efficient one (if there is such a thing):

[code]<?php

function dec_to_frac($number)
{
  // initialise the return vals
  $info = array('whole' => 0, 'frac' => '0');

  // get the integer base
  $integer = floor($number);

  // check if we're done already
  if ($integer == $number)
  {
    return array('whole' => $integer, 'frac' => 'nothing, you dummy');
  }

  // otherwise, get the remainder
  $decimal = $number - $integer;

  // setup an initial integer multiplier
  $i = 1;

  // find a legitimate denominator, the "long" way
  while (!isset($numerator) || (floor($numerator) != $numerator))
  {
    ++$i;
    $numerator = $decimal * $i;
  }

  // once it's done (and hopefully it hasn't been too long), we've got our denominator and numerator
  return array('whole' => $integer, 'frac' => $numerator.' / '.$i);
}

$numbers = array(1, 4.5, 7.625);
foreach ($numbers AS $num)
{
  $frac = dec_to_frac($num);
  echo $num.' becomes something like '.$frac['whole'].' and '.$frac['frac'].'<br>';
}

?>[/code]

run that one.  i've used barand's favourite test fraction (5/8); feel free to feed all sorts of other stuff to it and let me know if it fails.

Share this post


Link to post
Share on other sites
[quote author=Barand link=topic=103913.msg414307#msg414307 date=1155343993]
@sasa,

I'm playing devil's advocate again. Try

echo flo_to_fract(7.625);
[/quote]i change code[code]
<?php
function flo_to_fract($a){
if ($a==0) return '0';
$a1=floor($a);
if ($a1==0) $a1=''; else $a1 ="$a1 ";
$b=$a-$a1;
$c=strlen("$b")-2;
$c=round("1E+$c");
$b=round($b * $c);
if ($b==0) return $a1;
while ((($b%2)==0) and (($c%2)==0)) {
$b=$b/2;
$c=$c/2;
}
while ((($b%5)==0) and (($c%5)==0)) {
$b=$b/5;
$c=$c/5;
}
$a1.="$b/$c";
return $a1;
}
echo flo_to_fract(7.625);
?>
[/code]thanks for debug Barand

Share this post


Link to post
Share on other sites
I'll throw my hat in the ring. Here's my back-to-basics method of factorising the numerator and denominator then reducing both by the HCF.

[code]<?php
function factorise ($n) {
    $factors = array();
    $cand = 2;
    while ($n > 1 && $cand*$cand <= $n) {
        while ($n > 1 && $n % $cand == 0) {
            $factors[] = $cand;
            $n = $n / $cand;
        }
        $cand++;
    }
    if ($n > 1) $factors[] = $n;
    return $factors;
}

function array_mult($a) {
$prod = 1;
foreach ($a as $n) $prod *= $n;
return $prod;
}

function dec2frac ($n)  {
    list ($int, $dec) = explode ('.', "$n");
    if (!$dec) return "$int";
        // get numerator / denominator
    $p = strlen ($dec);
    $num = $dec;
    $den = pow (10, $p);
        // factorise them
    $fn = factorise ($num);
    $fd = factorise ($den);
        // remove common factors
    $com = array_intersect ($fd, $fn);
    $comval = array_mult($com);
    $num /= $comval;
    $den /= $comval;
    ////////// debug code /////////
    echo "<pre> $n\n\n";
    echo join (' . ', $fn), '<br>';
    echo '------------------------ : common : '. join (' . ', $com), '<br>';
    echo join (' . ', $fd), '<br><br></pre><br>';
   
    ////////////// end ////////////
   
    return "$int $num/$den";
}

$a = array (5.0, 1.75, 2.625, 4.997);  // test data (ie that data for which the program works)

foreach ($a as $n)  echo dec2frac ($n), '<br>';

?>[/code]

Share this post


Link to post
Share on other sites
or maybe[code]
<?php
function dec2frac ($n)  {
    list ($int, $dec) = explode ('.', "$n");
    if (!$dec) return "$int";
    $p = strlen ($dec);
    $den = pow (10, $p);
    $a = $den; //Euclidean algorithm
    $b = $dec;
    $c = $a % $b;
    while ($c){ $a = $b; $b = $c; $c = $a % $b; }
    //$comval = $b;
    $dec /= $b;
    $den /= $b;
    if (!$int) $int = ''; else $int = "$int ";  // no leading 0
    return "$int$dec/$den";
}

$a = array (0.5,'5.0', 1.75, 2.625, 4.997);  // test data (ie that data for which the program works)
foreach ($a as $n)  echo "$n -> ". dec2frac ($n) . "<br />\n";

?>
[/code]

Share this post


Link to post
Share on other sites
Excellent! Neater than my factorising. Had to look it up in wikipedia to see how it works.

http://en.wikipedia.org/wiki/Euclidean_algorithm

Share this post


Link to post
Share on other sites
i learned about the euclidean algorithm in abstract algebra, it's quite handy (not to say that i'm the one who applied it here).  here's a function that gives you a bit more information on the iterations.  the coding's a little sloppy, as i wrote it about a half year ago.

[code]<?php

function gcd($int_one, $int_two) {
// check if both values are zero, negative, or one is zero
if ($int_one <= 0 && $int_two <= 0) {
exit("Integers cannot both less than or equal to zero!");
} elseif ($int_one == 0 || $int_two == 0) {
$info['gcd'] = 0;
$info['dividends'][] = max($int_one, $int_two);
$info['divisors'][] = min($int_one, $int_two);
$info['quotients'][] = "n";
$info['remainders'][] = 0;
$info['implication'] = "Statement is true for all integers 'n'.";
return $info;
}
// assign max and min, and start euclidean algorithm
$max = max($int_one, $int_two);
$min = min($int_one, $int_two);
// euclidean algorithm arrays
$m = $n = $q = $r = array();
// define our starting dividend and divisor
$m[0] = $max;
$n[0] = $min;
// start our euclidean algorithm
for ($i = 0; $r[($i - 1)] !== 0; $i++) {
$q[$i] = floor(bcdiv($m[$i], $n[$i], 15));
$r[$i] = $m[$i] - bcmul($q[$i], $n[$i]);
$m[($i + 1)] = $n[$i];
$n[($i + 1)] = $r[$i];
}
// unset the last values for $m and $n
unset($m[$i], $n[$i]);
// reached a zero remainder - GCD is $n in the final step: $n[($i - 1)]
// return all iteration info as well, in case a breakdown is desired
$info['gcd'] = $n[($i - 1)];
$info['dividends'] = $m;
$info['divisors'] = $n;
$info['quotients'] = $q;
$info['remainders'] = $r;
// finally, return any implication that exists given the GCD
if ($info['gcd'] == 1)
$info['implication'] = "Integers are relatively prime.";
elseif ($info['gcd'] == abs($int_one) && $info['gcd'] == abs($int_two))
$info['implication'] = "Integers are absolutely equal - that is, integer one = +/- integer two.";
elseif ($info['gcd'] == abs($int_one) || $info['gcd'] == abs($int_two))
$info['implication'] = "Lower integer is a divisor of higher integer - that is, $min | $max.";
else
$info['implication'] = "The GCD delivers no clear implication about the integers.";
return $info;
}

$int1 = mt_rand(0, 500);
$int2 = mt_rand(0, 500);
$gcd = gcd($int1, $int2);
echo "<table border='1' cellspacing='0' cellpadding='10'>
<tr><td><strong>Resulting Equations</strong></td></tr>";
foreach ($gcd['dividends'] AS $j => $m)
echo "<tr><td>$m = {$gcd['quotients'][$j]} * {$gcd['divisors'][$j]} + {$gcd['remainders'][$j]}</td></tr>";
echo "</table>
<p>The GCD of $int1 and $int2 is {$gcd['gcd']} - its Euclidian Algorithm has a length of ".count($gcd['divisors']).".</p>
<p>{$gcd['implication']}</p>";

?>[/code]

Share this post


Link to post
Share on other sites

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.