Jump to content

Recommended Posts

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]
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]
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.
[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
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]
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]
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]
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

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.