Problem overview
The absolute value of a number is its distance from zero, so it is never negative. The method abs receives an Int named n and returns n without its sign: -5 becomes 5, 5 stays 5, and 0 stays 0. The task is to build this yourself, without calling the abs function that Scala provides.
The method takes and returns an Int, so the code below works on whole numbers. The logic is the same for any numeric type, decimals included.
Approach: only negatives change
Positive numbers and zero are already their own absolute value. Only a negative number has to change, and the change is one operation: negate it. Negating a negative number gives a positive one, because -(-5) is 5.
That gives a two-way decision, which is exactly what if and else express: if n is below zero, return -n; otherwise return n.
Step by step
- Test for a negative number. Write an
ifwhose condition isn < 0. Leave the body empty for the moment. - Negate inside the
if. Return-n. The unary minus flips the sign, so a negative input produces a positive result. - Handle everything else. Add
} else {on one line after theifbody, and returnnunchanged. Zero lands in this branch, which is correct, since the absolute value of 0 is 0.
The solution in Scala
class Solution {
def abs(n: Int): Int = {
if (n < 0) {
return -n
} else {
return n
}
}
}
The Scala details worth knowing:
- Return type. The signature
def abs(n: Int): Intdeclares the type of the result. A method that usesreturnmust declare its result type (leaving it out is a compile error), and the compiler checks that both branches produce anInt. returnis optional. In Scala the last expression of a block is its value, andif/elseis itself an expression. The same method can be written asif (n < 0) -n else n, and this is the usual style. The lesson's version with explicitreturnbehaves identically.- Unary minus.
-nis a method call on the integer, written with the operator syntax. It works on any numeric type.
Edge cases and common mistakes
- Zero.
abs(0)returns0. Whether zero goes to theifor theelsebranch gives the same answer, but writingn <= 0is unnecessary. - Forgetting the else. If the method has only the
ifwith areturnand nothing after it, the compiler reports a type mismatch (foundUnit, requiredInt) and hints that anelsepart is missing, since a non-negative input would have no value to produce. - Returning
nin the first branch. Returning the input unchanged when it is negative gives back the negative number. - The smallest
Int.Inthas 32 bits, and its range is not symmetric: the minimum is -2147483648 while the maximum is 2147483647. So-nforn = Int.MinValueoverflows silently and the result is still -2147483648. For ordinary inputs this never matters, but it is the one value where this method returns a negative number.
Testing
abs(-5)gives5.abs(250)gives250.abs(0)gives0.abs(-1)gives1.
