SitePoint Sponsor

User Tag List

Results 1 to 8 of 8
  1. #1
    SitePoint Member
    Join Date
    Nov 2008
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    problem with division in model

    I am trying to do some simple math in my model, but for some reason, it chokes on division, or at least when I use the \ symbol. I have tried many different iterations, and all math works and loops great til I try to divide two numbers. Am I using the wrong symbol here?

    def up
    n = up_votes
    x = up_votes + down_votes + neutral_votes
    y = x/n * 100
    return y
    end

    def down
    return ((up_votes + down_votes + neutral_votes)/down_votes ) * 100
    end

  2. #2
    Programming Team silver trophybronze trophy
    Mittineague's Avatar
    Join Date
    Jul 2005
    Location
    West Springfield, Massachusetts
    Posts
    16,443
    Mentioned
    160 Post(s)
    Tagged
    1 Thread(s)
    Hi danpberger, welcome to the forums.

    The only problems I can think of are
    1: You can not divide by zero (i.e. no up_votes or no down_votes).
    2: Precision problems

    The first you can fix by making sure that you're not trying to divide by zero.
    The second may require data type casting or rounding off. In other words, if you divide (floats) 152 by 7 do you really need the result to be (float) 21.71428571 ?? This could be causing an excessive use of resources. AFAIK, if the are ints, Ruby will truncate the result to an int "automatically".

  3. #3
    SitePoint Member
    Join Date
    Nov 2008
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the reply. I did make sure all votes are at least 1. (I'll go back and deal with 0 later, after I get this logic to work.) As for the second part of your response, I tries to use .round or .ceil, but that didn't change anything. It still just spits out 100 every time.

    def up
    n = up_votes
    x = (up_votes + down_votes + neutral_votes)
    y = (x/n).round * 100
    return y
    end

    Thanks so much.

  4. #4
    Programming Team silver trophybronze trophy
    Mittineague's Avatar
    Join Date
    Jul 2005
    Location
    West Springfield, Massachusetts
    Posts
    16,443
    Mentioned
    160 Post(s)
    Tagged
    1 Thread(s)
    This gives me 300 for both up and down
    Code Ruby:
    def up 
      up_votes = 1
      down_votes = 1
      neutral_votes = 1
     
      n = up_votes
      x = up_votes + down_votes + neutral_votes
      y = x/n * 100
      return y 
    end
     
    def down 
      up_votes = 1
      down_votes = 1
      neutral_votes = 1
     
      return ((up_votes + down_votes + neutral_votes)/down_votes ) * 100
    end
     
    puts up
    puts down

  5. #5
    SitePoint Member
    Join Date
    Nov 2008
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Again, thanks for the reply. I have tried all of this. If I use any other operator, plus, minus, multiply, this works great. It gives me the correct number for each iteration in my for loop in my view. But when I use the / for division, it breaks. There are no zeros in my database and the data types are all integers. So, I'm stumped!

  6. #6
    SitePoint Member
    Join Date
    Nov 2008
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    if I take the number and add .to_f, it works. I tried that before, but something else must have been amiss then. Now all looks good. Thank you!

  7. #7
    Programming Team silver trophybronze trophy
    Mittineague's Avatar
    Join Date
    Jul 2005
    Location
    West Springfield, Massachusetts
    Posts
    16,443
    Mentioned
    160 Post(s)
    Tagged
    1 Thread(s)
    If you add an int (a whole # no decimal places) to an int you get an int.
    If you multiply an int with an int you get an int.
    If you subtract an int from an int you get an int.
    But if you divide an int with an int you can get a float.

    If I run
    Code Ruby:
    def up 
      up_votes = 2
      down_votes = 3
      neutral_votes = 4
     
      n = up_votes
      x = up_votes + down_votes + neutral_votes
      y = x/n * 100
      return y 
    end
     
    def down 
      up_votes = 5
      down_votes = 6
      neutral_votes = 4
     
      return ((up_votes + down_votes + neutral_votes)/down_votes ) * 100
    end
     
    puts up
    puts down
    Up gives me
    400 (4.5 rounded down * 100)
    and down gives me
    200 (2.5 rounded down * 100)

    But if I add ".to_f" to the "vote" variables, I get
    450.0 and 250.0

    It may be that the division was rounding down to 1 and then giving you 100 as the result.

    Adding ".to_i" to the up and down results I get 450 and 250

    I guess depending on what kind of values you want/need to work with, you'll need to cast the variable's datatypes in the appropriate place. At least for the division.

  8. #8
    SitePoint Evangelist
    Join Date
    Feb 2006
    Location
    Worcs. UK
    Posts
    404
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Mittineague View Post
    But if you divide an int with an int you can get a float.
    No. If you divide an int with an int, you get an int (learnt the hard way ). Ruby will always round the result to the nearest (lower I think) integer. You need to force one or both of the entries to be a float, as float divided by float gives a float. (or int/float, or float/int)


Tags for this Thread

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
  •