# Truncation vs. Rounding

The first thing to notice is a pseudo-relation between rounding and truncating. Notice that:

• Rounding a number in the range [2.5, 3.5) returns the number 3
• Truncating a number in the range [3.0, 4.0) returns the number 3

Where a square bracket '[' denotes inclusion in the range, and a parenthesis '(' denotes non-inclusion in the range -- ie. [3.0, 4.0) is the range of all numbers between 3 and 4, including 3 but not including 4.

## Truncation

### What is truncation?

In simplest terms, truncation means to chop off the decimal portion of a number. This means:

• Truncating 3.3 returns 3
• Truncating 3.8 returns 3

And so on.

### How is it done?

Well, this is a really simple task for a person to perform. It involves writing down the number you want to truncate in pencil, then erasing everything after the decimal place :)

### Very funny...how do I do it on a computer?

Well, the algorithm differs slightly depending on whether you are truncating a positive value (greater than or equal to zero) or a negative value (less than zero).

In the interest of keeping things simple, let's just discuss the algorithm for truncating positive numbers (and the really motivated among you can see if you can figure out an algorithm for truncating negative numbers).

Notice that the domains on the truncation function and round function for any given return value are offset by exactly 0.5. Cool, huh?

So, if I had a value that would truncate to 5 (say 5.75, for example), I could simply subtract 0.5 from the value, and my new value (5.25 in the example) would round to 5.

So, an easy way to truncate a positive value is to simply subtract 0.5 from it and then round it.

### The Java code

So, the natural next question is, "How can I do this task in Java?" Thankfully, it's very simple :)

Since the Math.round method accepts a float value as an argument, this entire algorithm can be performed in a single step:

`truncated = Math.round(nontruncated - 0.5f);`

Points of note in the above line of code are:

• The round method is a static method in the class Math. Therefore, anytime you wish to call that method, the method name must be proceeded by the class name (ie: Math.round)
• Check the Java Class Documentation to see what type of values Math.round will accept as an argument and what types of values it will return. You will see that, if nontruncated is a float value, then Math.round will return an int. As such, truncated must be declared of type int.
• Note that when you subtract 0.5, you actually write it as 0.5f. This is because Java treats any decimal constant you write into your code as type double by default, and you must include a trailing 'f' if you wish the number to be treated as type float.

### For the curious

The algorithm of subtracting 0.5 from a value and then rounding it (which truncates a positive number) actually has so many uses that Java has been nice enough to include a method in its standard library that will do it for you.

In fact, in mathematics it is denoted as the "floor" function.

So, naturally, it has been included as a static method in the Math class called floor.

However, unlike the algorithm we developed above that takes a positive float and truncates it into an int value, the floor function both receives and returns a double value (you can confirm this in the Java Class Documentation).

Its sister function, "ceiling," performs a similar task: It adds 0.5 to a value and then rounds it (hint: this has something to do with how you would truncate a negative value).

Neat stuff, eh? Check out the Java Class Documentation, and try playing around with these functions when you have some spare time.

## Rounding to Two Decimal Places

Now let's look at the algorithm for rounding a float value to two decimal places.

### What is rounding to two decimal places?

It is a process that returns the closest finite number expressed to two decimal places. This means:

• Rounding 3.465 to two decimal places returns 3.47
• Rounding 3.464 to two decimal places returns 3.46

And so on.

### How is it done?

The first thing to notice when performing this task is that the process is nearly identical to rounding a decimal value to the nearest whole number, except the entire process is shifted over by two decimal places.

To explain briefly how a human would perform this task:

• Check first that there are more than two digits after the decimal. If there are not, then the process is completed without having to do anything.
• If the number does need to be rounded, look at the third digit after the decimal. If that digit is greater than or equal to five, add 0.01 to the number you are rounding. If the digit is less than or equal to four, do nothing.
• Finally, erase everything after the second digit after the decimal.

### It is even easier on a computer

The great thing about working in Java is that, with the methods provided to you in the Math class, you don't even need to think that much to round a number to two decimal places!

Remember our initial observation that rounding a number to two decimal places is identical to rounding a number to the nearest whole, except the process is shifted by two decimal places? Let's take advantage of that fact.

Looking at the Java Class Documentation, you will see that in the Math class, there is a static method called round that takes a float as an argument and returns the closest int value (in other words, it rounds the float to a whole number int).

This is almost what we want to do -- except it rounds to the wrong precision. But, there is an easy way around this. Think for a moment; what would happen if we multiplied our float value by 100, then rounded it, then divided by 100?

Try this process with a few example numbers, and you'll quickly see what we have accomplished. We shift the decimal two places to the right by multiplying by 100, which results in the round method returning our number with the required number of digits to the left of the decimal. Then, we divide by 100 to shift the decimal place two places to the left again, yielding our original number rounded to two decimal places.

For example:

• Let's round 3.6353 to two decimal places.
• Multiply by 100 to yield 363.53
• Round to the nearest whole number to get 364
• Divide by 100 to reposition the decimal, yielding the result 3.64

### The Java code

Much like the previous example, this algorithm is very simple to write in Java:

`roundedToTwoDecimals = Math.round(unrounded*100)/100f;`

Points of note in the above line of code are:

• Unrounded is a float.
• The round method is a static method in the class Math. Therefore, anytime you wish to call that method, the method name must be proceeded by the class name (ie: Math.round)
• Note that when you divide by 100 after rounding that you actually write 100f. This is because Java treats any whole-number constant you write into your code as type int by default, and you must include a trailing 'f' if you wish the number to be treated as type float. If you did not include the 'f' in the above line of code, both your divisor and dividend would be of type int, and you would perform integer (whole-number) rather than floating-point (decimal) division. Integer division returns only whole numbers, and would muck up the entire essence of the algorithm -- attempting to round a number to two decimal places (try it out and see what the result is for yourself).
• The dividend, which is `Math.round(unrounded*100)`, is an int as implied above. This is because Math.round's argument is a float, which means Math.round will return an int. Dividing an int by a float--in this case the divisor, 100f--returns a float. Thus, roundedToTwoDecimals must be a float for both compatibilitity, and to maintain the decimal places.