Like all things in ruby, numbers too are objects. They are instances of the Numeric class. If the number is an integer it will belong either to the Fixnum or Bignum class. If it is a float it belongs to the Float class. So how do we find out? Let’s call our friend irb and see,
As seen from above, we enter an integer number (in this case 7). In ruby this number is now an object. In order to find out what class this object belongs to we enter 7.class and as can be seen, irb evaluates it to be Fixnum. Similarly, if we enter a floating point number, we see that it belongs to class Float. If we assign 7 to a variable “a”, then “a” points to an object of type Fixnum and if we re-assign 7.0 to it, it then points to an object of type Float.
An object is an instance of a class. That is, the class is the generic (in this case number) and an object (7) is a specific (just like class: human, object: Suchitra). So an object inherits various traits from its class such as methods and we are able to perform various computations. For example, we can add two integers and get an integer answer; we can add two floating numbers and get a floating number answer and so on.
Like all of us have ancestors, ruby classes too have ancestor classes from which they inherit properties. If you want to check what the ancestor classes are of the Fixnum class, you can do so by typing,
Now we can see the entire list of parent classes of Fixnum, going all the way back to BasicObject (BasicObject is the parent class of all classes in ruby).
Experimenting with number objects: Since number objects are armed with various methods, we can do all kinds of manipulations in ruby. We can add, subtract, square, divide etc. etc. etc……………
However there are a few things that I have come across so far, that are done differently in ruby when dealing with numbers which would be good to keep in mind. For example,
1. When dividing two numbers, the division operator depends on the class of the operands. If both values are integers then truncating-integer division is performed. If either value is a Float then floating-point division is performed.
2. With integer division, -a/b = a/-b but may not equal –(a/b)
As can be seen -2/1 = 2/-1 = -(2/1) = -2, however, -5/2 = 5/-2 = -3 and –(5/2) = -2. In ruby with integer division truncation is towards negative infinity where as with languages like C/C++ truncates towards zero. In this example, the floating point result of -5/2 = 5/-2 = -2.5 which is truncated to -3. However with –(5/2), it first performs the floating point division of 5/2 = 2.5. Then truncates it to 2 and gives the negative integer which is -2.
3. The modulo (%) operator also differs from C.
With positive numbers (7%3 = 1) we get results similar to C. However -7%3 => 2. Two important points: The magnitude of the quotient differs and the sign differs (because in ruby the result is given the sign of the second operand). In our example, the floating point result of -7/3 is -2.33. Ruby rounds it down to -3 which is -9/3. So how do you get -7/3? To -9/3 we add 2/3. Thus, the answer is 2.
4. If you want to produce results similar to C, ruby has the “remainder” method which can be used