SitePoint Sponsor

User Tag List

Results 1 to 6 of 6
  1. #1
    Visible Ninja bronze trophy
    JeffWalden's Avatar
    Join Date
    Sep 2002
    Location
    Los Angeles
    Posts
    1,709
    Mentioned
    5 Post(s)
    Tagged
    0 Thread(s)

    Modulus Calculation Incorrect - I Think?

    Hey guys, this should be a simple situation but I'm crunching some numbers using the modulus operator and something just isn't right.

    This is working correctly:
    1161 / 32.25 = 36

    This, however, is not:
    1161 % 32.25 = 9

    If you crunch those numbers, you'll see that there is no remainder. As such, I have no idea where the value of 9 is coming from. My actual code is below, though it's not going to help much. Does anybody know of a bug with the modulus operator? Maybe I'm just missing something overly simple.

    PHP Code:
    $Remainder $Trade $PriceList;
    // $Remainder is 9 
    TAKE A WALK OUTSIDE YOUR MIND.

  2. #2
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,277
    Mentioned
    18 Post(s)
    Tagged
    0 Thread(s)
    I believe PHP only does modulus with integers, so it's actually doing 1161 % 32.
    "First make it work. Then make it better."

  3. #3
    Barefoot on the Moon! silver trophy Force Flow's Avatar
    Join Date
    Jul 2003
    Location
    Northeastern USA
    Posts
    4,606
    Mentioned
    56 Post(s)
    Tagged
    1 Thread(s)
    Try using the fmod function instead. The modulus operator is only intended to work with integers, and anything else tends to lead to unpredictable results.
    Visit The Blog | Follow On Twitter
    301tool 1.1.5 - URL redirector & shortener (PHP/MySQL)
    Can be hosted on and utilize your own domain

  4. #4
    SitePoint Wizard TheRedDevil's Avatar
    Join Date
    Sep 2004
    Location
    Norway
    Posts
    1,196
    Mentioned
    4 Post(s)
    Tagged
    0 Thread(s)
    Please be aware that fmod has floating point issue, so you cannot trust it either, unless your certain the number your compare against is in a specific range not affected.

    We ended up writing a code where we converted the number to hundreds (cents, to remove the decimal point), before running modulus and a few other tests to verify the result.

  5. #5
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,277
    Mentioned
    18 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by TheRedDevil View Post
    Please be aware that fmod has floating point issue, so you cannot trust it either
    Yup, you seem to be right. I looked through the comments on the fmod doc page, and found a couple examples that produce the wrong answer.

    PHP Code:
    $mod fmod(10.2);
    echo 
    "Got $mod, expected 0\n";

    $mod fmod(0.250.05);
    echo 
    "Got $mod, expected 0\n"
    Here's a function that seems to produce the correct answer in these cases.

    PHP Code:
    function yetAnotherMod($dividend$divisor)
    {
        
    $fractionalRemainder $dividend $divisor floor($dividend $divisor);

        return 
    $fractionalRemainder $divisor;

    "First make it work. Then make it better."

  6. #6
    Visible Ninja bronze trophy
    JeffWalden's Avatar
    Join Date
    Sep 2002
    Location
    Los Angeles
    Posts
    1,709
    Mentioned
    5 Post(s)
    Tagged
    0 Thread(s)
    Thanks guys! Never thought about the decimal issue. The function provided by Jeff worked great!
    TAKE A WALK OUTSIDE YOUR MIND.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •