## WeBWorK Main Forum

### mod (%) irregularities ?

by Zak Zarychta -
Number of replies: 4
I'm trying to implement a simple reduction of a fraction with the following

$numer = (($a*$d +$b*$c)*$f - ($b*$d*$e));$denom = ($b*$d*$f); my$count;
for ($count=2;$count<10; $count++) { if (($numer % $count == 0) && ($numer % $count == 0)) {$numer = $a/$count;
$denom =$b/$count;$count = $count-1; } } When in a conventional perl script for$numer = 75 and $denom = 21 the previous routine sets$numer = 25 and $denom =7. In my WeBWorK question 1 and 0.3333 are returned respectively for$numer and $denom. Why might this be so? Is this something to do with the mod symbol? Zak In reply to Zak Zarychta ### Re: mod (%) irregularities ? by D. Brian Walton - Zak, You have the wrong condition typed in the divisibility test (2nd should be$denom % $count) Your update of$numer and $denom should be:$numer = $numer/$count;
$denom =$denom/$count; Also, instead of decreasing count by 1, just change the if statement to a while statement. Finally, if you are only going to check a small group of possible divisors, you might think about changing$count to $prime and then use a short list of known primes. Try the following: my$prime;
foreach $prime (2, 3, 5, 7, 11, 13, 17, 19) { while (($numer % $prime == 0) && ($denom % $prime == 0)) {$numer = $numer /$prime;
$denom =$denom / $prime; } }  D. Brian Walton In reply to D. Brian Walton ### Re: mod (%) irregularities ? by Danny Glin - If you are looking to reduce fractions, there are some existing functions in PGauxiliaryFunctions.pl. In particular, a gcd function, and (as I just discovered) the reduce function. I use gcd to do this, so my code looks like: loadMacros("PGauxiliaryFunctions.pl"); ...$g = gcd($numer,$denom);
$numer =$numer/$g;$denom = $denom/$g;

Having just read the code for reduce, you should be able to simply do:
...
($numer,$denom) = reduce($numer,$denom);

One thing to note is that if you pass a negative fraction to reduce, it will return a negative numerator and a positive denominator.  I've never actually used this before, but looking at the code it should work as expected.

Danny
In reply to D. Brian Walton

### Re: mod (%) irregularities ?

by Paul Pearson -
Hi,

Are you trying to randomly generate a reduced fraction? Why not do something like

do {
$num = random(2,9,1);$den = random(2,9,1);
} until (
gcd($num,$den) == 1
);

Note that $num and$den above could be defined in terms of other scalars $a,$b, etc. all inside of the executable portion of do { execute }. I don't know how gcd( , ) handles negative integer inputs, but you can easily test that yourself.

If you need something more advanced, take a look at the xgcd method in the MatrixUnimodular.pl macro file located in OpenProblemLibrary/macros/FortLewis (or NationalProblemLibrary/macros/FortLewis).

https://github.com/openwebwork/webwork-open-problem-library/blob/master/OpenProblemLibrary/macros/FortLewis/MatrixUnimodular.pl

Best Regards,

Paul Pearson

### Re: mod (%) irregularities ?

by Alex Jordan -
If you load contextFraction.pl, then there is a Fraction Context with a Math Object Fraction that automatically reduces fractions (this is a flag that can be toggled.)

Context("Fraction.pl");
$fraction = Fraction($numer,$denom); I find it useful to then return to the Numeric Context Context("Numeric");$fraction = Compute("$fraction"); Or students might get error messages implying they should be entering a fraction, even when$fraction is actually a whole number.

If you have a Fraction Math Object and wish to extract the reduced numerator or denominator, first create an array from $f: @g =$f->value;
And then $g[0] is the numerator and$g[1] is the denominator. These are perl integers, not Math Objects, so you might want to set something like
$num = Compute($g[0]);
$den= Compute($g[1]);