Converting Strings to Numbers

Problem

Receive a value as a string and convert it to a number.

Caution

Methods attached to the Number object are part of ECMAScript 6 (ES6, the new standard of JavaScript). Older browsers that still in use, such as Internet Explorer 11 and below and Safari 7 and below, do not support these features (they work to the older ECMAScript 5 or ES5 standard). Check out http://kangax.github.io/es5-compat-table/es6/ for the current compatibility charts.

Solution

There are several ways to make this conversion. Global methods parseInt and parseFloat will convert strings into numbers as long as the strings are not using letters. Variables with numbers as strings can also be converted to numbers. The last example is implicit conversion where an equation is performed on a string.

Math is a global object that does not use a constructor. This means that all properties and methods using the Math object are static. You will see this in some of the following examples.

The Code

Listing 4-1. Converting a String Into a Number

var x = ‘1 '; Number(x);     // returns 1 Number.parseInt(x, 10) ; // returns 1 and uses a radix to make the browser use the decimal system Number.parseFloat(x) // returns 1 parseFloat('+1x2345x'); //returns 1 Number.parseFloat('+1234x567'); //returns 1234 typeof(parseInt(x)); // returns number typeof(parseFloat(x)); //returns number +x //returns 1.

How It Works

Because JavaScript is a loosely typed language, the interpreter will make type conversions automatically. Where most of the examples are explicit type conversion, the last instance is implicit using the unary plus operator .

The parseInt method has a second parameter called radix . The radix is the base number of unique digits. For example, using a value of 10 will ensure the parseInt method will use numbers 0 though 9. Using 10 as the radix is recommended. You can avoid unpredictable results by making parseInt use the decimal system.

The parseFloat method returns a floating-point number. If the first character cannot be converted into a number, the method will return NaN (not a number). It will parse characters up to a point where characters cannot be converted. For example, sign (+,-) numbers, with or without decimals and exponents, will be converted.

Both of these methods are included in the Number object and behave the same way. Once they are converted all the Arithmetic operators can be used.

Number.parsInt and Number.parseFloat do not work in IE 11 and below or in Safari.

Creating a Number Object

Problem

You want to create an object whose datatype is a number in order to work with numerical values.

Solution

In addition to converting strings to numbers, you can explicitly create a number object. The result is an object with the number datatype. If the value cannot be converted to number, the result will be NaN (Not a Number). Not using the new operator will result in type conversion. You can also use the global typeOf operator to check the datatype of a variable.

The Code

Listing 4-2. Creating an Object Wrapper to Work with Numbers

var myNumberObject = new Number(2); console.log(myNumberObject); if(myNumberObject.valueOf() === 2){    console.log(‘we are the same'); } console.log(typeof parseInt('2')); // returns number console.log(typeof parseFloat('2')); //returns number console.log(typeof parseFloat(myNumberObject)); //returns number

How It Works

JavaScript will take the value passed to the constructor and create a number object. If the value passed is a string, it will convert the string into a number; otherwise, it will return NaN . Because Number is a primitive value in JavaScript, to test both value and datatype the valueOf method is used to return the number.

Checking If a Value Is Not a Number

Problem

You receive data and you need to check if the value is a number.

Solution

Both the global method isNaN and the Number.isNaN method can be used. You can also check the datatype by using the typeof operator.

The Code

Listing 4-3. Using the isNaN Method on the Number Object to Check Value

var numberObject = new Number('things'); function checkIsNaN(value){   if(typeof value !== 'number'){     return 'is not a number';   }else{     return 'is a number';   } } checkIsNaN('1234'); //returns is not a number isNaN('things'); // returns true Number.isNaN(numberObject.valueOf()); //returns true Number.isNaN(4); //returns false Number.isNaN(NaN); //returns true

How It Works

Using the global isNaN method, parameters are converted to numbers , then evaluated. If you were to pass a string or number to the method on the number object, it will return false. This makes it possible to only pass parameters that can safely be converted to NaN but are not the same value. In addition, you can use the typeof operator and strict equality or inequality operators. One way to think of this would be, “is this not a number?”.

Formatting a Number to a Fixed Amount of Digits

Problem

You need to format numbers with a fixed amount of digits.

Solution

JavaScript contains methods that will fix the amount of digits. Depending on the method, the results may be different. The reason for this is how each method rounds numbers.

The Code

Listing 4-4. Fixing the Amount of Numbers after a Decimal Point

var numObj = 1.23456789; numObj.toPrecision(); //returns 1.23456789 numObj.toPrecision(2); //returns 1.2 numObj.toPrecision(5); //returns 1.2346 Five numbers total. Notice how it is rounded up numObj.toFixed(5); //returns 1.23457 Notice how it rounds up numObj.toFixed(2); //returns 1.2

How It Works

toPrecision() and toFixed() will both return a string with the formatted numbers. Using toPrecision will set the amount of digits used. When using toFixed, the amount of digits after the decimal point will be set.

The trunc() method will remove all numbers after the decimal, but has no support in Internet Explorer.

Checking to See If a Number Is Finite

Problem

You want to make sure the number being used is a finite number.

Solution

isFinite has a global function and one that is associated with the Number object as of ES6.

The Code

Listing 4-5. Check to See If a Number Is Finite

var myNumberObject = new Number(2); isFinite(myNumberObject); //returns true isFinite(2); //returns true isFinite('myNumberObject'); //returns false Number.isFinite(myNumberObject.valueOf()); //returns true Number.isFinite(myNumberObject); //returns false Number.isFinite('myNumberObject'); //returns false Number.isFinite(NaN); //returns false isFinite(NaN); //returns false isFinite(null); //returns true Number.isFinite(null); //returns false

How It Works

The global isFinite function will do type conversion while the version associated with the number object does not. If you're passing a number object to the global version, it will be treated like a number due to type conversion. Passing a string that cannot be converted into a number will return false. Values like null will be converted into a number and return true, while NaN will return false.

If you're using the method associated with the number object, no type conversion happens . Strings will always return false. If a number object is being passed, you will need to use the valueOf method so the isFinite method can evaluate the number and not the object.

Checking If a Value Is an Integer

Problem

You want to determine if the number are working with is a whole number.

Solution

JavaScript does not have an integer datatype; all numbers are really floating-point numbers. For these purposes, you want a number converted to a whole number without decimals. The methods round, ceil, and floor used with the math object will return integers and will convert strings into numbers. If the string cannot be converted, it will return NaN.

The Code

Listing 4-6. Checking for Integers

var myNumber = 1 Number.isInteger(myNumber);//returns true does not work in IE Number.isInteger('2'); //returns false does not work in IE Math.floor(1.6); //returns 1 Math.floor(1.4); //returns 1 Math.floor(NaN); //returns NaN Math.ceil(1.6); //returns 2 Math.ceil(1.4); //returns 2 Math.round(1.6); //returns 2 Math.round(1.4); //returns 1 Math.round(-1.5); //returns -1 Math.round(-1.6); //returns -2 Math.round('3.5'); //returns -4 Math.round('jenny'); //returns NaN Math.round(null); //returns 0

How It Works

JavaScript does not have an integer datatype; all numbers are really floating-point numbers. The engine that is interpreting the code can store small numbers as integers unless the number grows too large or a decimal is added. ES6 adds the isInteger method. This method returns true or false it does not do type conversion.

Formatting Numbers for Date Time and Currency

Problem

You want to take numbers and format them into percentages and currency.

Solution

The number object does not have built-in formatting functions. Because of this, there are a lot of third-party libraries and APIs to give you what you need. The ECMAScript Internationalization API has methods for date time and currency. The visualization library D3 also has formatting methods. The internationalization API works with IE 11, but not in Safari and the D3 library works with IE 9 and above.

The Code

Listing 4-7. Using the D3 Library and ECMAScript Internationalization API

d3.format('%')(1); // returns 100% d3.format(',')(1000000); //returns 1,000,000 d3.format("$,")(1250); //returns $1,250 d3.format("$,.2f")(1250);  //returns $1,250.00 d3.time.format('%Y-%m-%d').parse('1975-08-19'); //returns Tue Aug 19 1975 00:00:00 GMT-0400 (EDT) new Intl.NumberFormat().format(45000);   // returns 45,000 new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(45000); // returns &xxxFFE5;45,000 new Intl.DateTimeFormat('ja-JP', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }).format(new Date(1975, 07, 19)); //returns 1975年8月19日火曜日 new Intl.DateTimeFormat('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }).format(new Date(1975, 07, 19)); // returns Tuesday, August 19, 1975

How It Works

If you want to use D3, you can download it from D3js.org. Once you add it to your page, you can use the formatting functions. D3 uses a lot of method chaining. The first method describes the format that you want the numbers to be converted into. The second is the number to be converted. Converting time is similar; you add the format then the parse method will take the date you want to parse. There are clear examples of how to use these methods and more here: http://koaning.s3-website-us-west-2.amazonaws.com/html/d3format.html .

The internationalization API works in a similar way where you define how the formatting will work. Then you pass over what needs to be formatted. A full breakdown can be found on Mozilla's site: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat .

Creating a Random Number Generator

Problem

You want generate a random number between two values.

Solution

Use the random method in the Math object and round the results.

The Code

Listing 4-8. Creating a Random Number Generator Based on the Range of Two Numbers

function getRandomBetweenMinAndMax(min, max) {   return Math.floor(Math.random() * (max - min) + min); } function getRandomArbitrary(min, max) {   return Math.floor(Math.random() * (max - min + 1) + min); } getRandomBetweenMinAndMax(0,5); getRandomArbitrary(0,5);

How It Works

On its own, the random method in the Math object returns a floating point pseudo-random number in the range of 0 or 1. The result would be a fraction of a number that would then need to be rounded using the floor method. You can set a minimum and maximum range by creating a function that will set these values.

In your function, you pass over the maximum and minimum values. In order for JavaScript to understand these values, it needs to do a little math. Inside the parentheses, you subtract the maximum number from the minimum number. By itself that should give you the value of the minimum number. This is what's called the inclusive number . Outside the parentheses, you add the minimum number back and that will give JavaScript the maximum number. This is the exclusive number. This number will not be part of the results.

This will work fine but you end up not having the high number as part of the result since it's the excluded number. In order to shift this over one, you add one to the equation in the parentheses. This will raise the maximum value so the number you want to use is included in the results.

Finding the Absolute Value of a Number

Problem

You want the real number or non-negative value without worrying about the sign.

Solution

The abs method of the Math object will give you the non-negative number.

The Code

Listing 4-9. Determine the Absolute or Non-Negative Value of a Number

Math.abs()   //returns NaN Math.abs(-1)  //returns 1 Math.abs('-1')  // returns 1 Math.abs(null)  //returns 0 Math.abs('miho')   //returns NaN Math.abs('')  //returns 0

How It Works

The sbs() is a static method in the Math object. Since math does not have a constructor, Math.abs(value) is the correct way to use it. This method will do type conversion before creating the real number value. Empty strings will be converted to 0, while other strings will be converted to NaN. Not passing a value to this method will also result in NaN.

Using Math.max to Determine the Highest Number

Problem

Without performing a loop or any type of comparison function, you need to determine the highest number in a list or in an array.

Solution

Math.max can take a series of numbers and return the highest number in the list or an array.

The Code

Listing 4-10. Determine the Math.max Method to Return the Highest Number

Math.max(1,10) //returns 10 Math.max(-100,10) //returns 10 Using apply as part of the method call can define scope of the array. var myNumArray = [1,2,3,4,5,6,7,8,9]; Math.max.apply(null,myArray); //returns 9 This would give you the same result: Math.max.apply(this,myArray); //returns 9 Math.max.apply(myArray) //returns –Infinity Math.max(myArray) //Returns NaN

How It Works

Math.max is a static method so it is used as is. If no arguments are given to it, the answer is –Infinity. If any of the arguments cannot be converted into a number, then the answer will result in NaN.

If you are using an array and not putting values directly into the method, use the apply method to direct the browser to where it should find the array.

Returning the Square Root of a Number

Problem

You need to find the square root of a number.

Solution

The Math object has a static method called sqrt(). Passing any positive number to this method will result in the square root. Negative or strings will result in NaN.

The Code

Listing 4-11. Finding the Square Root of a Number

Math.sqrt('Roger') //result NaN Math.sqrt(1000); //result 31.622776601683793

How It Works

The static Math.sqrt() method will return the square root of a given number.

Using Coercion and Performing Equations

Problem

Depending on the order of your variables, JavaScript will treat them as strings or convert them into numbers.

Solution

Because JavaScript does type coercion, strings can be converted into numbers and used in equations dynamically. Depending on the order of the strings, numbers, and operators (+, -), the results can be different.

The Code

Listing 4-12. Difference Between String Concatenation and Number Conversion

var myNumber = ‘15'; //adding numbers console.log(myNumber + 5) // returns 155 console.log(5 + myNumber) //returns 515 //subtracting numbers console.log(5 – myNumber) // returns -10 console.log(myNumber – 5) //returns 10 var testNum = ‘7';     testNum += 7 // returns 77     testumber – ‘1' // returns 6 var machineType = ‘Tardis Type ‘;     machineType += 40 // returns Tardis Type 40 var num1 = 5; var num2= 5; console.log (‘the total is ‘ + (num1 + num2)); // returns the total is 10

How It Works

Because JavaScript is not a strongly typed language , it can change the datatype of your variables depending on context. If you start with a string on the left side and use the plus (+) operator, JavaScript will assume that you are concatenating values. This is why, in the previous examples, ‘15' + 5 turns into 115.

The opposite is true when using the minus operator (-). In this case, it will convert the string into a number and perform subtraction. This is why 7 – ‘-1' will return 6.

In the last example, JavaScript will just convert the number into a string and add it to the existing string.

If both variables are numbers, you can do the equation in parentheses and then covert them to a string later.

What's the Difference Between Math.floor() and Math.ceil() ?

Problem

When working with numbers, sometimes you need to round to the lowest or highest integer.

Solution

Use Math.floor() to round to the closest lowest integer and Math.ceil() when rounding to the closest highest integer.

The Code

Listing 4-13. The Difference Between Math.floor() and Math.ceil()

//depending on the numbers provided the method will either round up or down to the closest integer. Math.floor(5.6) //returns 5 Math.ceil(5.6) //returns 6

How It Works

Here each method rounds to either the highest or lowest integer.

Returning a Number in Reverse

Problem

You are given a number and are asked to give that number back in reverse. For example, if you are given 123 the result should be 321.

Solution

With JavaScript, there are many ways of doing this. The fastest way is to convert everything into a string and use the reverse method then turn everything back into a number. This is also a quick way to see if a something is a palindrome if you're asked on an interview, since the results should have the value.

In the second example, you can use a while loop and remove the last number of the first variable and add it to the second, each time checking if the value of the first number is not yet 0.

The Code

Listing 4-14. Reversing a Number by Splitting It into a String then Reversing It (a Version Without String Conversion)

var numSequence = 1234;  var reversedNumbers = Number(numSequence.toString().split(”).reverse().join(”)); console.log(reversedNumbers) // returns 4321 //with out converting to a string var = 123456789, b=0; while(a > 0){   b = b * 10;   b = b + parseInt(a%10);  a = parseInt(a/10); } console.log("Reversed number: " + b);

How It Works

The first example is very simple. Since you can do type conversion very quickly with JavaScript, you can chain a few methods together. All of this needs to take place inside either the Number() or parseInt() method, so the results can be converted back to the number datatype; otherwise, you end up with a string. Inside your chosen method, convert the whole number to a string using the toString() method. Chain the split(‘') method to that. Make sure that you have empty quotes inside the parentheses, because the split is based on the space between the characters. The result of this is now an array of strings. Add the reverse() method to reverse the order of the array. Then finally join the elements back into one string using the join(‘') method. To make sure you get a number datatype back, you can put the results in the browser console using the console.log() method and use typeof to return the datatype.

The second way does not use type conversion . This way, both variables are initialized. The second variable (in our case b) has a value of 0. All of the work is done inside a while loop. Each time you go through the loop, you check to see if the value of a is greater than 0. If it is, first take b and multiply it by 10. The next line will take the last number from a and add it to b, using a combination of the parseInt method and the modulo operator. This operator will take the a number divided by 10 and give you the remainder. In this case, this is the last number.

You may notice all the math is based on 10 in this example. We are using 10 in a similar way it is used in the parseInt() method as the radix. Every time we multiply b by 10, we ensure when the numbers are added together we get 987654321 and not 45.

Determining the Length of a Number

Problem

You are given a number and need to know the length, similar to knowing the length of an array.

Solution

The Number object does not have a length property. Similar to the last example, you can do this either with type conversion or without. One thing to point out—the second solution only works with positive numbers.

The Code

Listing 4-15. Determine First with String Conversion then Without

var myNum = 123456789; console.log(myNum.toString().split(‘').length); //without converting to a string var length = Math.log(555555555) * Math.LOG10E + 1 | 0; console.log(length);

How It Works

The first example is similar to the previous one. Convert the number to a string. Then turn the string into an array by using the split() method , then check the length.

The second example will take more time to explain. We first use the log() method of the Math object. Since it is a static method, you use it directly from the Math object. This gives you what is described as the natural logarithm of the number you provided. If it's given a negative number, it will return NaN.

Once you have that times the number by base 10, you use the LOG10E property of the Math object. This actually makes the number smaller and gets you closer to the right amount of numbers. Finally, add a bitwise OR operator. The number is then treated as a bit (1 or 0). If the value is 1, then add 1 and truncate the remaining numbers. Now you have the length of numbers.

Swapping Two Numbers Without a Temporary Variable

Problem

You need reverse the order of two numbers.

Solution

This goes under the category of questions you may get on an interview. To get this to work just involves some math that will reassign the value of each variable. The second variable is reassigned twice.

The Code

Listing 4-16. Determine First with String Conversion then Without

function swapNumbers(numb1, numb2){    console.log(‘starting order = ‘ + numb1 + ‘,' + numb2);    numb2 = numb2 – numb1; //is now -150    numb1 = numb1 + numb2; //is now 50    numb2 = numb1 – numb2; //is now 200    console.log(‘ending order = ‘ + numb1 + ‘,' + numb2); } swapNumbers(200,50);

How It Works

Since we can dynamically reassign the value of our variables, we just do a little math. We immediately start to reassign the values of the variables as soon as the function starts. To help, we will use round numbers.

  • num2 is reassigned to the value of 50 - 200 so now it is -150.

  • num1 is reassigned to the value of 200 + (-150) so now it is 50.

  • num2 is again reassigned to the value of 50 - (-150) so now it is 200.

The last line is the one to watch out for. Since it is minus a negative number , the result is the same as addition.