Beste PHP-hulpers,

Is het mogelijk om op een makkelijke wijze een breuk te vereenvoudigen in PHP?
Ik krijg de breuk aangeleverd als een string. Bijvoorbeeld "5/300".

Gr,
Rienus
als je goed controleerd kan je met eval() werken,
Maar onthou wel: eval = evil.
tenzij je erg goed controleerd, (alleen cijfers en /+-* toestaan
Ha Nico,

Bedankt voor je reactie. Indien ik het doe met eval, dan krijg ik de volgende error.

$breuk = eval("5/300");
Parse error: parse error in C:\wamp\www\test\index.php(12) : eval()'d code on line 1

Gr,
Rienus
Eval() heb je eigenlijk nooit nodig, zo ook niet in dit geval:

<?php
$breuk = '5/300';
list($nom, $denom) = explode('/', $breuk);

$uitkomst = $nom / $denom;
echo $uitkomst;
?>

[edit]Dit geeft alleen maar de decimale uitkomst van de breuk. Voor zover ik weet is er geen bestaande functie in PHP op de breuk te vereenvoudigen tot (in dit geval) 1/60.[/edit]

[size=xsmall]Toevoeging op 25/08/2010 10:26:19:[/size]

Uiteraard kun je er wel zelf een functie voor schrijven. Volgens mij moet dit in alle gevallen werken:

<?php
function vereenvoudig($breuk) {
if(!is_string($breuk) || substr_count($breuk, '/') != 1) {
return false;
}
else {
list($nom, $denom) = explode('/', $breuk);

for($i = $nom; $i > 0; $i--) {
if(is_int($denom / $i) && is_int($nom / $i)) {
$new_nom = $nom / $i;
$new_denom = $denom / $i;

break;
}
}

return $new_nom.'/'.$new_denom;
}
}

$breuk = '5/300';
echo vereenvoudig($breuk);
?>
Implementeer dit algortime:

Bij het vereenvoudigen van een breuk is het handig om de ggd te bepalen. 
Het getal boven en onder de breuk (respectievelijk de teller en de noemer) kan dan door de g.g.d worden gedeeld 
en zo verkrijgt men direct de grootst mogelijke vereenvoudiging. 
De breuk 24/102 wordt aldus vereenvoudigd tot 4/17. 
Een breuk van twee relatief prieme getallen kan niet vereenvoudigd worden.

Bijvoorbeeld: verklein 75/105:

    75= 3x5x5
    105= 3x5x7

Wat hebben ze gemeen? Het product 3x5.

Wat blijft er over? Bij 75 de factor 5 en bij 105 de factor 7.

    75/105= 5/7 

Wiki is je - speciaal voor Daniel Voogsgerd - goede vriend! (Stiekem toch beste hoor ;) )

Met vriendelijke groeten,
Jens
@Blanche
Volgens mij vereenvoudigd het script dat jij plaatst alle breuken maar één keer. En het script kan een breuk met een hogere waarde dan twee niet aan.

@Jens
Wiki is een goede vriend maar google is je beste vriend (:
Daniel, hoe bedoel je dat. Als ik bijvoorbeeld de breuk 1368/13338 neem, wordt dat netjes vereenvoudigd naar 4/39...

Kun je een voorbeeld geven van een breuk die volgens jou niet goed vereenvoudigd zou worden?
@Daniel, dat is ook geen probleem, want het zoekt direct naar de ggd.
Kan veel makkelijker, als je GMP hebt:
http://php.net/manual/en/function.gmp-gcd.php

Ofterwijl:

<?php
$breuk = '5/300';
list($nom, $denom) = explode('/', $breuk);

$gcd=gmp_gcd($nom,$denom);
echo ($nom/$gcd)."/".($denom/$gcd);
?>


[edit]
Heb net een functie gevonden waarmee je de GCD zelf uit kan rekenen, zonder GMP:
[/edit]

<?PHP
function gcd($x, $y){
    $x = abs($x);
    $y = abs($y);
    if($x + $y == 0){
        return "0";
    }else{
        while($x > 0){
            $z = $x;
            $x = $y % $x;
            $y = $z;
        }
        return $z;
    }
}
?>
Een ieder ontzettend bedankt voor zijn reactie. Hier kom ik een heel eind verder mee!

Gr,
Rienus

Reageren