why is rails/ruby automatically rounding to whole numbers.

Discussion in 'Ruby' started by Morgan Morgan, Jan 23, 2010.

  1. @wtf= 751 / 750

    returns 1 in the view

    @wtf= 3 / 750

    returns 0 in the view

    @wtf= 749 / 750

    returns 0 in the view.


    can somebody explain what's going on here. i'm just trying to calculate
    percents.
    --
    Posted via http://www.ruby-forum.com/.
     
    Morgan Morgan, Jan 23, 2010
    #1
    1. Advertising

  2. Morgan Morgan wrote:
    > @wtf= 751 / 750
    >
    > returns 1 in the view
    >
    > @wtf= 3 / 750
    >
    > returns 0 in the view
    >
    > @wtf= 749 / 750
    >
    > returns 0 in the view.
    >
    >
    > can somebody explain what's going on here. i'm just trying to calculate
    > percents.



    Apparently if you add a .0 it turns it into a precise number
    --
    Posted via http://www.ruby-forum.com/.
     
    Morgan Morgan, Jan 23, 2010
    #2
    1. Advertising

  3. Morgan Morgan

    Raul Jara Guest

    Re: why is rails/ruby automatically rounding to whole number

    Morgan Morgan wrote:
    > Morgan Morgan wrote:
    >> @wtf= 751 / 750
    >>
    >> returns 1 in the view
    >>
    >> @wtf= 3 / 750
    >>
    >> returns 0 in the view
    >>
    >> @wtf= 749 / 750
    >>
    >> returns 0 in the view.
    >>
    >>
    >> can somebody explain what's going on here. i'm just trying to calculate
    >> percents.

    >
    >
    > Apparently if you add a .0 it turns it into a precise number


    In ruby there are two kinds of numbers (really more than that, but let's
    just leave it at two for now) Fixnums and Floats. Fixnums are basically
    whole numbers or integers. Floats are any numbers with decimal places
    in them. Whenever you do math between two Fixnums, ruby assumes that
    you want a fixnum as an answer, and it will only provide a fixnum as a
    result. This is incredibly useful when working with arrays, because if
    an array is length 9 and you divide that by 2, you get 4, which is a
    usable index for an array. 4.5 wouldn't be. However if any math
    operation involve one number that is a float, the answer will be a
    float. So 1 (Fixnum) / 2 (Fixnum) = 0 (Fixnum). But 1.0 (Float) / 2
    (Fixnum) = 0.5 (Float).

    Is that clear?

    --
    Posted via http://www.ruby-forum.com/.
     
    Raul Jara, Jan 23, 2010
    #3
  4. Morgan Morgan wrote:
    > @wtf= 751 / 750
    >
    > returns 1 in the view
    >
    > @wtf= 3 / 750
    >
    > returns 0 in the view
    >
    > @wtf= 749 / 750
    >
    > returns 0 in the view.
    >
    >
    > can somebody explain what's going on here. i'm just trying to calculate
    > percents.
    >


    Ruby performs integer division when the numerator and the denominator
    are both integers. If either is a floating point number, it will perform
    floating point division. Therefore, simply call .to_f on either side of
    the division and you will get a floating point number.

    -Justin
     
    Justin Collins, Jan 23, 2010
    #4
  5. Morgan Morgan

    Guest

    On Fri, Jan 22, 2010 at 9:02 PM, Morgan Morgan <> wrote:
    > Morgan Morgan wrote:
    >> =A0 =A0 =A0 @wtf=3D 751 / 750
    >> =A0 =A0 =A0returns 1 in the view
    >>
    >> =A0 =A0 =A0 @wtf=3D 3 / 750
    >> =A0 =A0 =A0returns 0 in the view
    >>
    >> i'm just trying to calculate percents.

    >
    > Apparently if you add a .0 it turns it into a precise number


    http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_stdtypes.html

    $ irb
    irb(main):001:0> 1.class
    =3D> Fixnum
    irb(main):002:0> 1.0.class
    =3D> Float
     
    , Jan 23, 2010
    #5
  6. Morgan Morgan

    Josh Cheek Guest

    [Note: parts of this message were removed to make it a legal post.]

    On Fri, Jan 22, 2010 at 7:57 PM, Morgan Morgan <> wrote:

    > @wtf= 751 / 750
    >
    > returns 1 in the view
    >
    > @wtf= 3 / 750
    >
    > returns 0 in the view
    >
    > @wtf= 749 / 750
    >
    > returns 0 in the view.
    >
    >
    > can somebody explain what's going on here. i'm just trying to calculate
    > percents.
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >

    First an example. Lets say you were managing a school, you had two
    Philosophy courses, the first course has 1 student, the second course has 6
    students. You want to balance them, how do you do this? With 7 students
    total, and 2 courses, 7/2 is 3.5, so we chop one student in half and put 3.5
    students into each course. Unfortunately, students who have been chopped in
    half tend to be poor learners (and the janitor hates cleaning up blood). So
    instead, you put 3 in the first course, and 4 in the second.

    In this case, we have 7/2, and expect 3 and 4, rather than 3.5 and 3.5

    So why do you get the results you do in your examples? It has to do with how
    variables are stored. In lower level languages, the program has to know
    ahead of time what kind of number to expect (because of how memory is
    managed), so you specifically declare to the translator what kind of
    variables you are storing. When you declare something as an int, it cannot
    then become a float, because that is not what you have declared (it is fixed
    at the time that the program code is generated, and can't change at run time
    if you get 10/6 instead of 10/5, this is called static).

    So when you say 1/2, the answer may be 0.5, but that is a number with a
    decimal place (called float, which stands for floating point, meaning that
    the decimal place can move around between digits, for example 1.23 vs 12.3),
    but the variable you are storing it in may be an integer, so it has no way
    to store this float. In order to store it, the result is made into an
    integer by removing everything after the decimal place (known as
    truncating).

    This is how things have been for a very long time, and now that dynamic
    languages are becoming popular, they are largely maintaining this behaviour,
    because integers and floats are typically used in very different ways, so it
    would complicate a lot of situtions if they could switch back and forth
    without you explicitly saying it should be allowed. For example, if you have
    some code that you want to be executed some number of times that was
    calculated (called a loop), then if the calculation returns 5 it is straight
    forward, but it could come back as 5.2 or 5.3, or some other non integer.
    What does it mean to execute code 5.3 times? In places where discrete
    quantities are expected, how do they deal with the remainder? It does not
    make sense to have 4.5 students in a class, and it does not make sense to
    execute the code 5.3 times. We expect integer quantities.

    So in most languages, integers and floats are considered to be separate
    things, and will not switch back and forth unless you specifically say to do
    so.

    In 751 / 750, those are both integers, the interpreter assumes that if you
    are dividing two integers, you want the result to be an integer as well,
    since the result is about 1.0013 it simply truncates the remainder, leaving
    one. When you say 749/750, it does the same thing, but this time the result
    is about 0.9987, so it truncates the remainder, leaving zero.

    This is one facet of the issue, but the other is that it is not simple to go
    from floating point back to integer. A number like 1/3 is 0.3 with the three
    repeating. This cannot be represented with any finite number of digits, so
    if you multiplied it by three, expecting to get one again, how would you
    know that the next digit after the last one was also a three? How would you
    go from that number back to the integer one? For example, if floating point
    numbers could store 4 decimal places, then 16667/50000, and 8333/25000, and
    1/3 would all look like 0.3333, but only the last one should return the
    integer 1, when multiplied by 3. So there are issues with converting from
    floats back to integers as well.

    We could just make all numbers floating points, or even generalize them to
    more abstract representations, such as stored functions like the square root
    of 2 (which has an infinite number of non-repeating digits), but then it
    would be difficult to quickly compare them to other numbers, and we couldn't
    know how much room they take to store (necessary in many languages, and for
    lots of useful things. For example, to access databases quickly, we need to
    know how much room a given field takes so we can calculate the location of
    the next field and go there directly without looking at all the information
    in between. Or so we can make sure that there will be enough room to store
    it on the device we have selected). We also wouldn't be able to quickly do
    heavy math operations on these abstract representations. So we accept a
    representation that is not precise, the float. It's a trade off. But it
    prevents us from knowing for sure that 0.3333 times 3 is 1, so generally we
    do not allow conversion to floating points unless that is really what we
    need for the given step. We keep track of where we want our integers, and
    where we want our floats.

    You can see, there is a lot of ambiguity with numbers, and numbers that
    track their decimal place are used in very different ways than integer
    numbers, which are usually selected because they come in discrete
    quantities.

    This is why we consider the two to be different, which is why the
    interpreter does not immediately convert integer numbers into floating point
    numbers, which is why 751/750 is one, and 749/750 is zero. Integer divided
    by integer assumes the result should be integer, but 751/750.0 is
    1.00133333333333, because one of the parameters was a float, so it assumes a
    float result is acceptable.

    Most languages behave in this manner.

    Hope that helps, just remember when dividing integers, the remainder will be
    truncated, so if you need the remainder, convert one of the arguments to a
    float first.
     
    Josh Cheek, Jan 23, 2010
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. C

    Rounding Numbers

    C, Aug 25, 2003, in forum: ASP .Net
    Replies:
    2
    Views:
    505
  2. \A_Michigan_User\
    Replies:
    2
    Views:
    923
    \A_Michigan_User\
    Aug 21, 2006
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,076
    Smokey Grindel
    Dec 2, 2006
  4. asutic

    rounding of 4 unsigned char numbers

    asutic, Aug 1, 2008, in forum: C Programming
    Replies:
    2
    Views:
    272
    Herbert Kleebauer
    Aug 1, 2008
  5. Ja Bo
    Replies:
    4
    Views:
    118
    Ja Bo
    Dec 29, 2006
Loading...

Share This Page