Friday, June 3, 2016

Scala Numeric Value Types and Math

Now that we've done an overview of Scala, let's get into what computers do best—math.

In languages such as Java, numeric types are generally primitives of some sort. Scala is purely Object Oriented, so numeric types are always objects. Having numeric types as objects means that methods affecting numbers are called on the numeric types directly. All numeric types in Scala are AnyVal objects.

What that means is that 1+1 and 1.+(1) are the same thing in Scala. The first example does not have the dot or the parenthesis, but both the dot and parenthesis are optional in Scala. For anyone familiar with Java-like languages, the second example looks a lot like a function or method, because it is. They both are. The mathematical operators in Scala are just method calls on AnyVal objects.
In an app, the previous examples would look like this,




object Testing extends App {
  val result = 1 + 1
  println( result )
}

and this,


object Testing extends App {
  val result = 1.+(1)
  println( result )
}

The idiomatic way to handle standard operators for Numbers in Scala is to always leave off the dot and the parens. You might use the dot and parens for other math calls, but not for the standard operators.

The standard operators for Scala are *, /, +, -, and %. Where * is multiplication. The forward slash is division. Plus is addition and minus is subtraction. And finally, the percent sign is modulus that returns the remainder of division.

Most numbers you use in Scala are Int's. Int's are integers or whole numbers. Int's are the default type of numeric value. When Scala sees a number, it usually assumes it is an Int. Int's have no fractional part or decimal point. If you think about that for a moment, you might ask what happens when you divide Int's in Scala. If you have never programmed computers before, division seems a bit unusual in languages like Scala. Division gives you the integer portion of the results, but drops any fractional portion of the result.

This is where modulus (the % sign) comes in handy. If you want to know the remainder left after the division of Int's, they you use the % sign.

The following Scala code prints 3.


object Testing extends App {
  val result = 10 / 3
  println( result )
}

And the following Scala code prints 1. 10 % 3 is said out loud as "Ten mod three" in case you where wondering.


object Testing extends App {
  val result = 10 % 3
  println( result )
}

Now, you might not think that having a special operator for getting the remainder from integer division is handy, but it really comes in useful. In a very basic example, what if you want to find out if a number is even. Divide the number by 2 with the modulus operator. (That is 10 mod 2 for those geeks among you.) If you get a result of 0, then you have an even number.

The following code checks that 10 is an even number. (Don't worry about the if statement. We'll get into those in other tutorials.)


object Testing extends App {
  
  val prime = 0;
  
  val numberToCheck = 10
  val result = numberToCheck % 2
  
  if (result == prime) {
    println( numberToCheck + " is a even number." )
  } else {
    println( numberToCheck + " is NOT a even number." )
  }
}

Sometimes, you really, really, badly want a decimal point. Scala can do that. Decimals in most computer programming languages are not very accurate, meaning the precision is not infinite in nature. However, if you don't care about precision, or don't need a highly precise decimal, they Double's are usually the way to go.

All you have to do to use Double's is include a decimal place in one of the numbers. That means 10 is an Int, but 10.0 is a Double.

In the following example, a Double 10.0 is divided and results in the value 3.3333333333333335 being printed.


object Testing extends App {
  
  val result = 10.0 / 3
  println( result );
  
}

Obviously, the value 3.3333333333333335 is not the infinite precision needed when dividing 10 by 3, but for many applications, it is good enough.

For the record, Scala's full list of numeric types, all of which are objects, are Double, Float, Long, Int, Short, and Byte. Double and Float are both used for decimal math. Floats are smaller versions of Double. Long's behave like Int's but  have more memory given to them by the computer, so they can hold bigger numbers than Int's. Short's are smaller versions of Int's, but almost never used. You can pretty much forget that Short's exist. (Really, I'm not kidding. Forget about Short's.) Bytes are a lot like small versions of Int's that can hold only very small values. Bytes are useful when interacting with computers, networks, and doing graphics.

For now, stick to using Double's and Int's. No one will think less of you, and many seasoned programmers don't use Float's or Short's, and rarely use Byte's.

No comments:

Post a Comment