6

I'm randomly generating repeated decimals using this code...

do{
    $divisor_array = array(3, 6, 9, 11, 22, 33);
    $divisor = $divisor_array[array_rand($divisor_array)];
    $number = mt_rand(1, 100);

    $decimal_value = $number / $divisor;
} while (strlen($decimal_value) < 5);

echo $number / $divisor;

I want to then display that number with the repeating bar over the repeating part.

Example: 5.83434343434343....
would be 5.8<span style="text-decoration: overline;">34</span>

Any ideas on how to do this if the repeating decimals are being randomly generated?

gtilflm
  • 1,389
  • 1
  • 21
  • 51
  • 1
    DO you have a limit on the amount of repeating patterns you are looking to match? if not this could be very difficult. for instance if the repeating section is very large. if you're only interested in matching smaller ones, like the one above where there are only a few digits in the pattern it wouldn't be too difficult. – Bryan Dec 03 '13 at 04:28
  • I think it would be best to limit the repeating sections to 1-3 digits. Is that what you were asking? – gtilflm Dec 03 '13 at 04:34
  • yes, in that case it's not very difficult, do you plan on showing a maximum number of decimal places even when there is no repeat? – Bryan Dec 03 '13 at 04:37
  • ??? The way I'm doing this, I'm always going to get a repeating decimal. – gtilflm Dec 03 '13 at 04:43
  • not if the repeating section is 456789 and you're looking for repeating sections of 3 or less.Not that it isn't repeating, but it makes no difference. i guess the question is simply what is the maximum number of decimal places to show? – Bryan Dec 03 '13 at 04:44
  • Let's say 3. So, something like 1.452452452... – gtilflm Dec 03 '13 at 04:46
  • Yeah i got that part, but if the number is 1.1234567767899943435423312334533333333333333 how far out would you go to look for a repeat? or would you just chop it at say five digits and show 1.12345 with no overline? – Bryan Dec 03 '13 at 04:55
  • Well, I'm going to get a repeating decimal no matter based on the code I'm using, but to answer your question, let's chop it at 5 digits. – gtilflm Dec 03 '13 at 04:57
  • This question could be of help: http://stackoverflow.com/questions/1315595/algorithm-for-detecting-repeating-decimals – Gerald Schneider Dec 03 '13 at 07:59
  • another one: http://stackoverflow.com/questions/8946310/how-to-know-the-repeating-decimal-in-a-fraction – Gerald Schneider Dec 03 '13 at 08:01

1 Answers1

4

Gotta say this isn't as easy as i thought it'd be. but i got it working. I'm sure there is a more efficient way of doing this, hopefully someone else will improve upon this. Especially the part where it gets printed.

$number1 =  $number / $divisor;
if(findRepeat( $number1 ) !== false)
{
    $result = findRepeat($number1);
    $leadingNum = strstr($number1, '.', true);
    $nonRepeat = substr($number1, strpos($number1, '.') + 1 , $result['position']);
    if($nonRepeat == '')
        $nonRepeat = '.';

    $repeat = substr($number1,strpos($number1,$nonRepeat) + strlen($nonRepeat), $result['patternSize']);
    $nonRepeat = $nonRepeat == '.' ? '.' : '.'.$nonRepeat;
    echo $leadingNum.$nonRepeat."<span style='text-decoration:overline'>".$repeat."</span>";

}
else
  echo number_format( $number1 , 6);

now for the function

function findRepeat($number)
{
    $maxLength = 6;
    $decimal = substr($number, strpos($number,'.') + 1 );
    if(strlen($decimal) >= $maxLength )
        $decimal = substr($decimal,0, $maxLength);
    else
        $maxLength = strlen($decimal);

    for($i =0; $i < $maxLength - 3; ++$i)
    {
        //check for single repeition
        if( $decimal[$i] == $decimal[$i + 1] &&  $decimal[$i + 1] == $decimal[$i+2])
            return array('position'=>$i,'patternSize'=>1);
        //triple repetition
        if(substr($decimal,$i,3) == substr($decimal, $i + 3, 3) )
            return array('position'=>$i,'patternSize'=>3);
        //double repetition
        if(substr($decimal,$i,2) == substr($decimal, $i + 2, 2) )
            return array('position'=>$i,'patternSize'=>2);
    }

    return false;
}
Bryan
  • 3,449
  • 1
  • 19
  • 23
  • I keep hitting the "else" every time in your if/else statement. Also, I had to change `$number` to `$dec_number` in the `findRepeat` function. – gtilflm Dec 03 '13 at 06:09
  • i made a change, i used static numbers to test it, calculate the number before feeding it to the function. i tested with your code and it works this way – Bryan Dec 03 '13 at 06:16
  • if you're changing a parameter you'll need to change all of it's occurrences in the function as well, but I just tested it like this with your number generator and it worked. – Bryan Dec 03 '13 at 06:18
  • server is on an older version of php so i had to use substr instead of strstr, but the rest of the code is the same including your number generator. http://isthisoffensiv.comule.com/test.php – Bryan Dec 03 '13 at 06:35
  • Awesome! This works great. I had no idea of how to approach this and your solution seems to be working well. Thanks! – gtilflm Dec 03 '13 at 14:56
  • great, if you want me to elaborate lets start a chat and i can break it down for you. – Bryan Dec 04 '13 at 06:55