63

I want to check if a number is divisible by 6 and if not I need to increase it until it becomes divisible.

how can I do that ?

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Utku Dalmaz
  • 9,780
  • 28
  • 90
  • 130

11 Answers11

141
if ($number % 6 != 0) {
  $number += 6 - ($number % 6);
}

The modulus operator gives the remainder of the division, so $number % 6 is the amount left over when dividing by 6. This will be faster than doing a loop and continually rechecking.

If decreasing is acceptable then this is even faster:

$number -= $number % 6;
Wilfred Hughes
  • 29,846
  • 15
  • 139
  • 192
ZoFreX
  • 8,812
  • 5
  • 31
  • 51
30
if ($variable % 6 == 0) {
    echo 'This number is divisible by 6.';
}:

Make divisible by 6:

$variable += (6 - ($variable % 6)) % 6; // faster than while for large divisors
Bandi-T
  • 3,231
  • 1
  • 20
  • 15
6
$num += (6-$num%6)%6;

no need for a while loop! Modulo (%) returns the remainder of a division. IE 20%6 = 2. 6-2 = 4. 20+4 = 24. 24 is divisible by 6.

Ponkadoodle
  • 5,777
  • 5
  • 38
  • 62
  • I think this is wrong - you are adding the remainder to the number. So if the number was 8, remainder is 2, you add the remainder 2 to 8, to get the result: 10. 10 is not divisible by 6 – Bandi-T Jan 19 '10 at 01:38
  • 1
    This will add 6 to the number if it is already divisible by 6. – Justin Smith Jan 19 '10 at 01:40
4

So you want the next multiple of 6, is that it?

You can divide your number by 6, then ceil it, and multiply it again:

$answer = ceil($foo / 6) * 6;
zneak
  • 134,922
  • 42
  • 253
  • 328
  • That's an insightful algorithm. – Karl Jan 19 '10 at 01:46
  • 6
    Boo! Why use floating-point when you don't have to! :) It is also non-portable, because int/int division in many languages will give a (truncated) integer result, so ceil will never see a need to round it up to the next integer value, therefore the expression will give the wrong result. – Bandi-T Jan 19 '10 at 01:47
  • 2
    I second that, using floating point for what is essentially an integer problem is horrible and may not give the right answer in all situations. – ZoFreX Jan 19 '10 at 03:01
  • I think choosing not to use the modulus operator in this instance is a bit weird... – Bryan M. Jan 19 '10 at 03:19
3

I see some of the other answers calling the modulo twice.

My preference is not to ask php to do the same thing more than once. For this reason, I cache the remainder.

Other devs may prefer to not generate the extra global variable or have other justifications for using modulo operator twice.

Code: (Demo)

$factor = 6;
for($x = 0; $x < 10; ++$x){  // battery of 10 tests
    $number = rand( 0 , 100 );
    echo "Number: $number Becomes: ";
    if( $remainder = $number % $factor ) {  // if not zero
        $number += $factor - $remainder;  // use cached $remainder instead of calculating again
    }
    echo "$number\n";
}

Possible Output:

Number: 80 Becomes: 84
Number: 57 Becomes: 60
Number: 94 Becomes: 96
Number: 48 Becomes: 48
Number: 80 Becomes: 84
Number: 36 Becomes: 36
Number: 17 Becomes: 18
Number: 41 Becomes: 42
Number: 3 Becomes: 6
Number: 64 Becomes: 66
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
  • 2
    How long do you think it takes to calculate modulo? 1ns, maybe 30 if we're talking about floats. How long do you think it takes to store it to memory and then load it? 2ns if you're lucky, hundreds of ns if it hits a cache page that's already in use and needs to be dumped to RAM first. And that doesn't even count for all the stuff PHP needs to do to manage a variable. A good compiler would use registers for both, but we're talking about a language where each variable is an object. And assignment in conditionals is bad because it looks like a bug. Also, whitespace please. – John Dvorak Jan 29 '18 at 02:48
  • That's a rather rude downvote don't you think? I can add whitespace if you like. But this answer provides correct outcomes in a way slightly different from the rest. – mickmackusa Jan 29 '18 at 02:52
  • 1
    and, of course... don't forget the difference in developer time - much more important than a couple of ns spend by the CPU. – John Dvorak Jan 29 '18 at 02:54
  • I didn't make any claims about shaving time. I merely suggested it is more DRY. Please undownvote. This is bullying. There is nothing wrong with my answer. – mickmackusa Jan 29 '18 at 02:56
  • 1
    "correct outcomes" isn't the only criterion that makes a useful answer. Not everything needs to be DRIed to the bone. DRY is a tool to make readable code. Does caching the modulo make your code more readable? – John Dvorak Jan 29 '18 at 02:56
  • 1
    Downvotes are a way to rate the usefulness of an answer. There's nothing rude about them. Also, why do you think it was my downvote? – John Dvorak Jan 29 '18 at 02:58
  • I have added a new perspective to the page. If you don't like it or don't find it useful to you, then don't upvote it. You could have just commented and left it alone for someone else to consider. – mickmackusa Jan 29 '18 at 03:00
  • 1
    what I'm saying: overuse of DRY can make the code worse. Your code is a borderline case, only adding one line to cache the modulo, but there are far worse victims to the policy and that's why I'm considering a flat "DRY up everything" a bad advice. – John Dvorak Jan 29 '18 at 03:03
  • 1
    Clarifying that "DRY helps readability in this case but it's not always the primary goal" should help... – John Dvorak Jan 29 '18 at 03:05
2

Use the Mod % (modulus) operator

if ($x % 6 == 0) return 1;


function nearest_multiple_of_6($x) {
    if ($x % 6 == 0) return $x;    

    return (($x / 6) + 1) * 6;
}
Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
1

Simply run a while loop that will continue to loop (and increase the number) until the number is divisible by 6.

while ($number % 6 != 0) {
    $number++;
}
James Simpson
  • 13,488
  • 26
  • 83
  • 108
  • The naive method saves programmer time, and my boss/client is always on about that. – Karl Jan 19 '10 at 01:47
1

Assuming $foo is an integer:

$answer = (int) (floor(($foo + 5) / 6) * 6)
Florent
  • 12,310
  • 10
  • 49
  • 58
martinr
  • 3,794
  • 2
  • 17
  • 15
0

For micro-optimisation freaks:

if ($num % 6 != 0)
    $num += 6 - $num % 6;

More evaluations of %, but less branching/looping. :-P

C. K. Young
  • 219,335
  • 46
  • 382
  • 435
0

Why don't you use the Modulus Operator?

Try this:

while ($s % 6 != 0) $s++;

Or is this what you meant?

<?

 $s= <some_number>;
 $k= $s % 6;

 if($k !=0)    $s=$s+6-$k;
?>
Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
  • I think this is wrong - you are adding the remainder to the number. So if the number was 8, remainder is 2, you add the remainder 2 to 8, to get the result: 10. 10 is not divisible by 6. – Bandi-T Jan 19 '10 at 01:37
  • Yeah I had missed something. Corrected now. – Prasoon Saurav Jan 19 '10 at 01:39
-1
result = initial number + (6 - initial number % 6)
Otiel
  • 18,404
  • 16
  • 78
  • 126
Rudy
  • 9
  • 1