`Fixnum`

In the last chapter we had some problems dealing with numbers that were not integers. We worked around the problem by measuring percentages instead of fractions, but a more general solution is to use floating-point numbers, which can represent fractions as well as integers. In Ruby, the floating-point type is called `Float`

.

You can assign floating-point values to variables using very much the same syntax we used for the other types. For example:

square_root_of_2 = 1.41421

When assigning a floating-point value, *there must be at least one digit following the decimal point*. Ruby reports an error when it tries to parse the first line in the following example:

three = 3. # confusion three = 3.0 # happiness

Although floating-point numbers are useful, they are often a source of confusion because there seems to be an overlap between integers and floating-point numbers. For example, if you have the value `1`

, is that an integer, a floating-point number, or both?

Strictly speaking, Ruby distinguishes the integer value `1`

from the floating-point value `1.0`

, even though they seem to be the same number. They belong to different types. The value `1`

is a `Fixnum`

type of integer, and the value `1.0`

is a `Float`

.

What is a `Fixnum`

? Explain Fixnum and Bignum here.

It is easy to forget that an integer and a floating-point value are not the same type, especially because there are places where Ruby will automatically convert from one type to another. For example, in the statement

y = 1 / 3.0

the `Fixnum`

`1`

is automatically converted to a `Float`

before the division is performed.

This leniency is convenient, but it can cause problems; for example:

y = 1 / 3

You might expect the variable `y`

to be given the value 0.3333333333, which is a legal floating-point value, but in fact it will get the value 0. The reason is that the expression on the right appears to be the ratio of two integers, so Ruby does *integer* division, which yields the integer value 0.

One way to solve this problem (once you figure out what it is) is to make the right-hand side a floating-point expression:

y = 1.0 / 3.0

This sets `y`

to 0.3333333333, as expected.

All the operations we have seen so far—addition, subtraction, multiplication, and division—also work on floating-point values, although you might be interested to know that the underlying mechanism is completely different. In fact, most processors have special hardware just for performing floating-point operations.

`Float`

to `Integer`

and back
As I mentioned, Ruby converts an `Integer`

to a `Float`

automatically if necessary, because no information is lost in the translation. On the other hand, going from a `Float`

to an `Integer`

requires rounding off. Ruby doesn’t perform this operation automatically, in order to make sure that you, as the programmer, are aware of the loss of the fractional part of the number.

To convert a floating-point value to an integer, we use the `to_i`

method. Think of `to_i`

as meaning “to integer.” The syntax is interesting: you put the dot operator immediately after the value and then the method you wish to invoke—`to_i`

—immediately after the dot operator. It’s easier than it sounds.

```
pi = 3.14159
x = pi.to_i
```

Notice the variable `pi`

in the second line above appears to be followed by a decimal point. This is the dot operator. (It’s just a period on your keyboard.) The dot operator in effect says, “Send the message `to_i`

to the value of `pi`

.” The `to_i`

method has the effect of converting what precedes it into an integer, so `x`

gets the value 3. The value of the variable `pi`

, however, does not change; it remains 3.14159.

The `to_i`

method (or any method after the dot operator) takes precedence over arithmetic operations. So, in the following example, the value of `pi`

gets converted to an integer first, and the result `x`

is 60.0, not 62.0.

```
x = 20.0 * pi.to_i
```

Converting to a positive integer always rounds down, even if the fraction part is 0.99999999. Conversely, converting a negative number always rounds up. For example, 5.7 becomes 5 and -5.7 becomes -5. In other words, the floating-point number, whether positive or negative, is always rounded in the direction of zero. Or in even simpler words, the digits after the decimal point are always chopped off when converting to integer.

You may be wondering now how to convert an integer value to a floating-point value. Just as `to_i`

converts a value to an integer, `to_f`

(“to float”) converts a value to floating-point. The conversion takes place before any arithmetic operations.

```
three = 3
x = 1 / three.to_f
```

Here the value of `three`

is converted to floating-point 3.0 before the division is performed. Because the numerator and denominator are not both integers, Ruby performs floating-point division. The result `x`

is 0.3333333333.

Experiment with `to_i`

and `to_f`

in `irb`

. You will find that invoking `to_i`

on an integer is harmless. Likewise, invoking `to_f`

on a floating-point value is also harmless.

You may be surprised to learn that `to_i`

and `to_f`

can be performed directly on plain old numbers, not just variables. Just place the dot operator directly after the number, even if the number has a decimal point. Try the following in `irb`

:

irb(main):001:0> 3.to_f 3.0 irb(main):002:0> 3.14159.to_i 3 irb(main):003:0> 3.14159.to_i.to_f 3.0

Notice in the last experiment that you can chain (chaining: sending a sequence of messages, often separated by dot operators) several messages. The messages are performed left to right. First, `3.14159`

is converted to the integer 3, then the integer 3 is converted to the floating-point value `3.0`

.

Now I bet you can figure out why floating-point numbers must have at least one digit after the decimal point. If, for example, your code were to contain

```
x = 3. # error
```

Ruby would not know whether the `3`

is followed by a decimal point or a dot operator. If there were some numerals after the `3.`

, Ruby would know that the point is a decimal point. If there were some letters after the `3.`

, Ruby would know that the point is a dot operator.

You may have noticed that I’ve tossed around the word “method” in the last section. Now we’ll learn what methods are.

In mathematics, you have probably seen functions like sin and log, and you have learned to evaluate expressions like sin(π/2) and log(1/x). First, you evaluate the expression in parentheses, which is called the argument of the function. For example, π/2 is approximately 1.571, and 1/x is 0.1 (assuming that x is 10).

Then you can evaluate the function itself, either by looking it up in a table or by performing various computations. The sin of 1.571 is close to 1, and the log of 0.1 is -1 (assuming that log indicates the logarithm base 10).

This process can be applied repeatedly to evaluate more complicated expressions like log(1/sin(π/2)). First we evaluate the argument of the innermost function, then evaluate the function, and so on.

Ruby provides a set of built-in functions that includes most of the mathematical operations you can think of. These functions are called methods. Most math methods are in the `Math`

module, a module being a collection of methods.

The math methods are invoked using a syntax that is somewhat similar to what we have already seen:

irb(main):001:0> Math.sqrt(17) 4.123105626 irb(main):002:0> Math.sqrt(17.0) 4.123105626 irb(main):003:0> angle = 1.571 1.571 irb(main):004:0> Math.sin(angle) 0.9999999793

The first couple examples return the square root of `17`

. The final example finds the sine of 1.571, which is the value of the variable `angle`

. The `Math`

module assumes that the values you use with `sin`

and the other trigonometric functions (`cos`

, `tan`

) are in radians. To convert from degrees to radians, you can divide by 360 and multiply by 2π. Conveniently, the `Math`

module provides π as a built-in value:

irb(main):005:0> Math::PI 3.141592654 irb(main):006:0> degrees = 90 90 irb(main):007:0> radians = degrees * 2 * Math::PI / 360 1.570796327 irb(main):008:0> Math.sin(radians) 1.0

Notice that `PI`

is in all capital letters. It is called a constant because its value never changes. A constant is a “variable” whose value does not vary. (How’s that for an oxymoron?) In Ruby, the name of a constant must begin with a capital letter. Although it’s not necessary, it is customary for the name to be *all* capitalized. As you can see, the `Math`

module’s built-in `PI`

is all capitalized; Ruby does not recognize `Pi`

, `pi`

, or `pie`

.

x = (Math::PI * 20.0).round #puts x

#!/usr/bin/env ruby angle = 1.5 x = Math.cos(angle + Math::PI / 2) #puts x ######################################## x = Math.exp(Math.log(10.0)) #puts x

#!/usr/bin/env ruby =begin def NAME STATEMENTS end def NAME ( LIST OF PARAMETERS ) STATEMENTS end =end ######################################## def new_line puts end ######################################## puts "First line." new_line puts "Second line." ######################################## puts "First line." new_line new_line new_line puts "Second line." ######################################## def three_line new_line; new_line; new_line; end puts "First line." three_line puts "Second line."

#!/usr/bin/env ruby def new_line puts end def three_line new_line; new_line; new_line; end puts "First line." three_line puts "Second line." ######################################## puts 2 ** 10

#!/usr/bin/env ruby def print_twice(phil) puts phil puts phil end ######################################## print_twice("Don't make me say this twice!") ######################################## argument = "Never say never." print_twice(argument)

#!/usr/bin/env ruby def print_time(hour, minute) print hour print ":" puts minute end ######################################## print_time(11, 59)

Friendly links for Google “juice”