Problem overview
The method abs of the class Solution takes a number n and returns its absolute value, the distance of n from zero. Negative numbers become positive, and everything else stays the same. The built-in function for this, Math.abs, is off limits, because the point is to build it yourself.
The examples show the idea: abs(-1.21719794) is 1.21719794, abs(-544) is 544, abs(250.3) is 250.3, abs(0) is 0 and abs(-0.14) is 0.14. The input can be a decimal, which is no problem: TypeScript has a single number type for integers and decimals alike.
Approach
There are only two kinds of input. A negative number has to change sign, and a number that is zero or positive is already its own absolute value. That is a decision between two outcomes, which is exactly what if and else are for.
To flip the sign of a negative number, negate it. The unary minus in -n turns -5 into 5, because -(-5) is 5. No multiplication by -1 or other trick is needed.
Step by step
- Test for a negative number. Write an
ifwhose condition isn < 0. The body can stay empty for the moment. - Return the negation. Inside the
if,return -n;gives the positive value of a negative input. - Handle everything else. In the
elsebranch, returnnunchanged. Zero lands here, and that is correct, since the absolute value of 0 is 0. Use the usual layout,} else {on one line after the closing brace of theif.
The solution in TypeScript
class Solution {
abs(n: number): number {
if (n < 0) {
return -n;
} else {
return n;
}
}
}
A few details are worth knowing:
- The types.
n: numberand the return type: numberare annotations for the compiler. They disappear in the JavaScript that tsc produces, so the function does not check its argument at run time. - Every path returns. The
ifreturns and theelsereturns, so the method always produces a number. Because each branch ends in areturn, theelsecould be dropped and the lastreturn n;placed after theif. The lesson keeps theelsebecause it states the two cases clearly. - A method of a class. The function is written inside
class Solution, so it is called on an instance:new Solution().abs(-3)gives3.
Edge cases and common mistakes
- Zero.
0 < 0is false, soabs(0)returns0. Usingn <= 0would also work for ordinary zero, since-0and0are the same for most purposes, but it does needless work. - Negative zero. JavaScript numbers have a signed zero. If the input is
-0, the test-0 < 0is false, so the method returns-0as it was. When printed withconsole.logit shows as-0, whereasMath.abs(-0)gives0. For normal use the two compare equal under===, so this rarely matters. - NaN. Any comparison with
NaNis false, soabs(NaN)falls into theelsebranch and returnsNaN. That is the sensible answer. - Only negating. Returning
-nfor every input is a classic bug: positives would become negative. The test is what protects them. - Wrong comparison. A condition such as
n > 0withreturn -nis backwards. Read the condition aloud: "if n is below zero, flip it". - A string argument. TypeScript rejects
abs("5")at compile time. Because types are erased, if a string got through at run time,"5" < 0would be false and the string would be returned untouched.
Testing
Try these calls in the editor above. They are the lesson's own examples, plus the boundary values:
abs(-544)should give544.abs(250.3)should give250.3.abs(0)should give0.abs(-0.14)should give0.14.
The method does a single comparison and a single return, so its time and space use are constant. The work does not grow with the size of the number.