Jump to content


Photo

convert integer to fraction


  • Please log in to reply
12 replies to this topic

#1 ghgarcia

ghgarcia
  • Members
  • PipPipPip
  • Advanced Member
  • 53 posts
  • LocationFlorida

Posted 11 August 2006 - 08:31 PM

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
George

#2 hitman6003

hitman6003
  • Members
  • PipPipPip
  • Advanced Member
  • 1,807 posts

Posted 11 August 2006 - 09:46 PM

It's not pretty, but it works:

$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>";
		}
	}
}


#3 ghgarcia

ghgarcia
  • Members
  • PipPipPip
  • Advanced Member
  • 53 posts
  • LocationFlorida

Posted 11 August 2006 - 10:00 PM

Thanks for the fast replay. It works fine for me.

George
George

#4 Barand

Barand
  • Moderators
  • Sen . ( ile || sei )
  • 18,016 posts

Posted 11 August 2006 - 11:09 PM

What if

$a = array(6.5, 7.25, 1.625);
If you are still using mysql_ functions, STOP! Use mysqli_ or PDO. The longer you leave it the more you will have to rewrite.

Donations gratefully received






moon.png

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts

#5 hitman6003

hitman6003
  • Members
  • PipPipPip
  • Advanced Member
  • 1,807 posts

Posted 11 August 2006 - 11:11 PM

I didn't say it was perfect.

#6 sasa

sasa
  • Staff Alumni
  • Advanced Member
  • 2,804 posts
  • LocationHrvatska

Posted 12 August 2006 - 12:44 AM

try
<?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);
?>


#7 Barand

Barand
  • Moderators
  • Sen . ( ile || sei )
  • 18,016 posts

Posted 12 August 2006 - 12:53 AM

@sasa,

I'm playing devil's advocate again. Try

echo flo_to_fract(7.625);
If you are still using mysql_ functions, STOP! Use mysqli_ or PDO. The longer you leave it the more you will have to rewrite.

Donations gratefully received






moon.png

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts

#8 akitchin

akitchin
  • Staff Alumni
  • Advanced Member
  • 2,516 posts
  • LocationCalgary, AB, Canada

Posted 12 August 2006 - 03:30 AM

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):

<?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>';
}

?>

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.

#9 sasa

sasa
  • Staff Alumni
  • Advanced Member
  • 2,804 posts
  • LocationHrvatska

Posted 12 August 2006 - 07:12 AM

@sasa,

I'm playing devil's advocate again. Try

echo flo_to_fract(7.625);

i change 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);
?>
thanks for debug Barand

#10 Barand

Barand
  • Moderators
  • Sen . ( ile || sei )
  • 18,016 posts

Posted 12 August 2006 - 10:11 AM

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.

<?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>';

?>

If you are still using mysql_ functions, STOP! Use mysqli_ or PDO. The longer you leave it the more you will have to rewrite.

Donations gratefully received






moon.png

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts

#11 sasa

sasa
  • Staff Alumni
  • Advanced Member
  • 2,804 posts
  • LocationHrvatska

Posted 12 August 2006 - 01:22 PM

or maybe
<?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";

?>


#12 Barand

Barand
  • Moderators
  • Sen . ( ile || sei )
  • 18,016 posts

Posted 12 August 2006 - 06:12 PM

Excellent! Neater than my factorising. Had to look it up in wikipedia to see how it works.

http://en.wikipedia....idean_algorithm
If you are still using mysql_ functions, STOP! Use mysqli_ or PDO. The longer you leave it the more you will have to rewrite.

Donations gratefully received






moon.png

|baaGrid| easy data tables - and more
|baaChart| easy line, column and pie charts

#13 akitchin

akitchin
  • Staff Alumni
  • Advanced Member
  • 2,516 posts
  • LocationCalgary, AB, Canada

Posted 12 August 2006 - 07:21 PM

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.

<?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>";

?>





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users