Very often, calculations in JavaScript do not give exactly the results we want. Of course, we can do whatever we want with numbers - round up or down, set ranges, cut off unnecessary numbers to a certain amount decimal places, it all depends on what you want to do next with this number.

Why is rounding necessary?

One of the interesting aspects of JavaScript is that it doesn't actually store integers, we work straight away with floating point numbers. This, combined with the fact that many fractional values ​​cannot be expressed in a finite number of decimal places, in JavaScript we can get results like this:

0.1 * 0.2; > 0.020000000000000004 0.3 - 0.1 > 0.19999999999999998
For practical purposes, this inaccuracy does not matter, in our case we are talking about an error in quintillion parts, however, this may disappoint some. We can get a few strange result and when working with numbers that represent currency values, percentages, or file sizes. In order to correct these inaccuracies, we just need to be able to round the results, and it is enough to set the decimal precision.

Rounding numbers has practical use, we may be manipulating a number within some range, for example we want to round the value to the nearest whole number rather than working only with the decimal part.

Rounding decimal numbers

To clip a decimal number, use toFixed or the toPrecision method. Both of them take a single argument that specifies, respectively, how many significant figures (that is, the total number of digits used in the number) or decimal places (the number after the decimal point) the result should include:
  1. If an argument is not defined for toFixed(), it will default to zero, which means 0 decimal places, the argument has a maximum value of 20.
  2. If no argument is given to toPrecision, the number is left untouched
let randNum = 6.25; randNum.toFixed(); > "6" Math.PI.toPrecision(1); > "3" randNum = 87.335; randNum.toFixed(2); > "87.33" randNum = 87.337; randNum.toPrecision(3); > "87.3"
Both the toFixed() and toPrecision() methods return a string representation of the result, not a number. This means that when summing a rounded value with randNum, it will produce a concatenation of strings rather than a sum of numbers:

Let randNum = 6.25; let rounded = randNum.toFixed(); // "6" console.log(randNum + rounded); > "6.256"
If you want the result to be a numeric data type, then you will need to use parseFloat:

Let randNum = 6.25; let rounded = parseFloat(randNum.toFixed(1)); console.log(rounded); > 6.3
Please note that values ​​of 5 are rounded except in rare cases.

The toFixed() and toPrecision() methods are useful because they can not only cut off the fractional part, but also add decimal places, which is convenient when working with currency:

Let wholeNum = 1 let dollarsCents = wholeNum.toFixed(2); console.log(dollarsCents); > "1.00"
Note that toPrecision will produce the result in scientific notation if the number of integers is greater than the precision itself:

Let num = 123.435 num.toPrecision(2); > "1.2e+2"

How to Avoid Rounding Errors with Decimals

In some cases, toFixed and toPrecision rounds the value 5 down and up:

Let numTest = 1.005; numTest.toFixed(2); > "1.00"
The result of the calculation above should have been 1.01, not 1. If you want to avoid a similar error, we can use the solution proposed by Jack L Moore, which uses exponential numbers for the calculation:

Function round(value, decimals) ( return Number(Math.round(value+"e"+decimals)+"e-"+decimals); )
Now:

Round(1.005,2); > 1.01
If you want a more robust solution than the one shown above, you can go to MDN.

Machine epsilon rounding

An alternative method for rounding decimal numbers was introduced in ES6. Machine epsilon rounding provides a reasonable margin of error when comparing two floating point numbers. Without rounding, comparisons may produce results similar to the following:

0.1 + 0.2 === 0.3 > false
We use Math.EPSILON in our function to get a valid comparison:

Function epsEqu(x, y) ( return Math.abs(x - y)< Number.EPSILON * Math.max(Math.abs(x), Math.abs(y)); }
The function takes two arguments: the first is the current calculation, the second is the expected result. It returns a comparison of the two:

EpsEqu(0.1 + 0.2, 0.3) > true
All modern browsers already support ES6 mathematical functions but if you want support in browsers like IE 11, use polyfills.

Trimming the fractional part

All methods presented above can round to decimal numbers. In order to simply cut a number to two decimal places, you must first multiply it by 100, and then divide the resulting result by 100:

Function truncated(num) ( return Math.trunc(num * 100) / 100; ) truncated(3.1416) > 3.14
If you want to adapt the method to any number of decimal places, you can use bitwise double negation:

Function truncated(num, decimalPlaces) ( let numPowerConverter = Math.pow(10, decimalPlaces); return ~~(num * numPowerConverter)/numPowerConverter; )
Now:

Let randInt = 35.874993; truncated(randInt,3); > 35.874

Round to the nearest number

To round a decimal number to the nearest number up or down, whichever we're closest to, use Math.round():

Math.round(4.3) > 4 Math.round(4.5) > 5
Note that "half the value", 0.5 is rounded to big side according to the rules of mathematics.

Round down to the nearest whole number

If you want to always round down, use Math.floor:

Math.floor(42.23); > 42 Math.floor(36.93); > 36
Please note that rounding down works for all numbers, including negative numbers. Imagine a skyscraper with an infinite number of floors, including floors on the bottom level (representing negative numbers). If you are in an elevator on the lowest level between 2 and 3 (which represents a value of -2.5), Math.floor will take you to -3:

Math.floor(-2.5); > -3
But if you want to avoid this situation, use Math.trunc , which is supported in all modern browsers(except IE/Edge):

Math.trunc(-41.43); > -41
On MDN you will find a polyfill that will provide support for Math.trunc in browsers and IE/Edge.

Round up to the nearest whole number

On the other hand, if you always need to round up, use Math.ceil. Again, remember the infinite elevator: Math.ceil will always go "up", regardless of whether the number is negative or not:

Math.ceil(42.23); > 43 Math.ceil(36.93); > 37 Math.ceil(-36.93); > -36

Rounding up/down to the required number

If we want to round to the nearest multiple of 5, the easiest way is to create a function that divides the number by 5, rounds it, and then multiplies it by the same amount:

Function roundTo5(num) ( return Math.round(num/5)*5; )
Now:

RoundTo5(11); > 10
If you want to round to multiples of your value, we use a more general function, passing in the initial value and the multiple:

Function roundToMultiple(num, multiple) ( return Math.round(num/multiple)*multiple; )
Now:

Let initialNumber = 11; let multiple = 10; roundToMultiple(initialNumber, multiple); > 10;

Fixing a number in a range

There are many cases where we want to get a value of x that lies within a range. For example, we might need a value between 1 and 100, but we ended up with a value of 123. To fix this, we can use min (returns the smallest of a set of numbers) and max (returns the largest of any set of numbers). In our example, the range is from 1 to 100:

Let lowBound = 1; let highBound = 100; let numInput = 123; let clamped = Math.max(lowBound, Math.min(numInput, highBound)); console.log(clamped); > 100;
Again, we can reuse the operation and wrap the whole thing in a function, using the solution proposed by Daniel X. Moore:

Number.prototype.clamp = function(min, max) ( return Math.min(Math.max(this, min), max); );
Now:

NumInput.clamp(lowBound, highBound); > 100;

Gaussian rounding

Gaussian rounding, also known as banker's rounding, involves rounding to the nearest even number. This rounding method works without statistical error. The best decision was suggested by Tim Down:

Function gaussRound(num, decimalPlaces) ( let d = decimalPlaces || 0, m = Math.pow(10, d), n = +(d ? num * m: num).toFixed(8), i = Math.floor (n), f = n - i, e = 1e-8, r = (f > 0.5 - e && f< 0.5 + e) ? ((i % 2 == 0) ? i: i + 1) : Math.round(n); return d ? r / m: r; }
Now:

GaussRound(2.5) > 2 gaussRound(3.5) > 4 gaussRound(2.57,1) > 2.6
Decimal in CSS:

Since JavaScript is often used to create positional mappings for HTML elements, you might be wondering what would happen if we generated decimal values ​​for our elements:

#box ( width: 63.667731993px; )
The good news is that modern browsers will respect decimal values ​​in the block model, including percentage or pixel units.

Sorting

Very often we have to sort some elements, for example, we have an array of game records, and they must be organized in descending order of player rank. Unfortunately, standard method sort() has some surprising limitations: it works well with common English words, but immediately breaks down when it encounters numbers, unique characters, or uppercase words.

Sorting alphabetically

It would seem that sorting an array alphabetically should be a simple task:

Let fruit = ["butternut squash", "apricot", "cantaloupe"]; fruit.sort(); > "apricot", "butternut squash", "cantaloupe"]
However, we run into a problem as soon as one of the elements is uppercase:

Let fruit = ["butternut squash", "apricot", "Cantalope"]; fruit.sort(); > "Cantaloupe", "apricot", "butternut squash"]
This is because, by default, the sorter compares the first character represented in Unicode. Unicode is unique code for any symbol, regardless of platform, regardless of program, regardless of language. For example, if you look at the code table, the character "a" has the value U+0061 (in hexadecimal 0x61), while the character "C" has the code U+0043 (0x43), which comes earlier in the Unicode table than the character "a".

To sort an array that may contain mixed case first letters, we need to either convert all elements temporarily to lower case, or define our sort order using the localeCompare() method with some arguments. As a rule, for such a case, it is better to immediately create a function for repeated use:

Function alphaSort(arr) ( arr.sort(function (a, b) ( return a.localeCompare(b, "en", ("sensitivity": "base")); )); ) let fruit = ["butternut squash ", "apricot", "Cantaloupe"]; alphaSort(fruit) >
If you want the array sorted in reverse alphabetical order, simply swap the positions of a and b in the function:

Function alphaSort(arr) ( arr.sort(function (a, b) ( return b.localeCompare(a, "en", ("sensitivity": "base")); )); ) let fruit = ["butternut squash ", "apricot", "Cantaloupe"]; alphaSort(fruit) > ["Cantaloupe", "butternut squash", "apricot"]
Here it is worth noting that localeCompare is used with arguments, we also need to remember that it is supported by IE11+, for older versions of IE, we can use it without arguments, and in lowercase:

Function caseSort(arr) ( arr.sort(function (a, b) ( return a.toLowerCase().localeCompare(b.toLowerCase()); )); ) let fruit = ["butternut squash", "apricot", "Cantaloupe"]; caseSort(fruit) > ["apricot", "butternut squash", "Cantaloupe"]

Numeric sort

All this does not apply to the example we talked about above about the array of game records. With some numeric arrays, sorting works just fine, but at some point the result can be unpredictable:

Let highScores = ; highScores.sort(); >
The thing is that the sort() method performs a lexicographic comparison: which means that the numbers will be converted into a string and the comparisons will again be made by matching the first character of that string in the order of the characters in the Unicode table. Therefore, we again need to define our sort order:

Let highScores = ; highScores.sort(function(a,b) ( return a - b; )); >
Again, to sort the numbers into reverse order, swap the positions of a and b in the function.

Sorting a JSON-like structure

And finally, if we have a JSON-like data structure represented as an array of game records:

Let scores = [ ( "name": "Daniel", "score": 21768 ), ( "name": "Michael", "score": 33579 ), ( "name": "Alison", "score": 38395 ) ];
In ES6+, you can use arrow functions:

Scores.sort((a, b) => b.score - a.score));
For older browsers that do not have this support:

Scores.sort(function(a, b) ( return a.score - b.score ));
As you can see, sorting in JavaScript is a rather obscure thing, I hope that these examples will make life easier somehow.

Working with power functions

Exponentiation is an operation originally defined as the result of repeatedly multiplying a natural number by itself; the square root of a is the number that gives a when squared. We could use these functions constantly in everyday life in mathematics lessons, including when calculating areas, volumes, or even in physical modeling.

In JavaScript, the power function is represented as Math.pow(), and in the new ES7 standard, a new exponentiation operator was introduced - " * * ".

Exponentiation

To raise a number to the nth power, use the Math.pow() function, where the first argument is the number that will be raised to the power, the second argument is the exponent:

Math.pow(3,2) > 9
This form of notation means 3 squared, or 3 × 3, which leads to the result 9. Another example can be given, of course:

Math.pow(5,3); > 125
That is, 5 cubed, or 5 × 5 × 5, is equal to 125.

ECMAScript 7 is the next version of JavaScript, in principle, we can use the new proposed exponentiation operator - * *, this form of notation may be more descriptive:

3 ** 2 > 9
On this moment Support for this operator is quite limited, so its use is not recommended.

The power function can be useful in a variety of situations. A simple example, calculating the number of seconds in an hour: Math.pow (60,2).

Square and cube roots

Math.sqrt() and Math.cbrt() are the opposite of Math.pow(). As we remember, the square root of a is the number that gives a when squared.

Math.sqrt(9) > 3
At the same time, the cube root of a is a number that gives a when raised to a cube.

Math.cbrt(125) > 5
Math.cbrt() was only recently introduced into the JavaScript specification, and is therefore only supported in modern browsers: Chrome 38+, Firefox and Opera 25+, and Safari 7.1+. You will notice that Internet Explorer isn't on this list, but you'll find a polyfill on MDN.

Examples

Of course, we can use non-integer values ​​in one of these functions:

Math.pow(1.25, 2); > 1.5625 Math.cbrt(56.57) > 3.8387991760286138
Please note that this also works quite well when using negative argument values:

Math.pow(-5,2) > 25 Math.pow(10,-2) > 0.01
However, this won't work for square root:

Math.sqrt(-9) > NaN
From mathematical analysis we know that an imaginary number refers to the square roots of negative numbers. And this may lead us to another technique for working with complex numbers, but that's another story.

You can use fractions in Math.pow() to find the square and cube roots of numbers. Square root uses an exponent of 0.5:

Math.pow(5, 0.5); // = Math.sqrt(5) = 5 ** (1/2) > 2.23606797749979
However, due to the vagaries of floating point, you can't exactly guess the correct result:

Math.pow(2.23606797749979,2) > 5.000000000000001
In such situations, you will have to resort to cutting off signs from the number or rounding to some value.

Some people, for unknown reasons, in JavaScript confuse the Math.pow() function with Math.exp() , which is the exponential function for numbers in general. Note: in English language"exponent" is translated as "exponent", so this is more likely to apply to English speakers, although there are alternative names for exponent, such as index, power.

Mathematical constants

Working with mathematics in JavaScript is made easier by a number of built-in constants. These constants are properties of the Math object. It is worth noting that constants are written in uppercase, not CamelCase notation.

Math.abs, parseInt, parseFloat

Working with numbers in JavaScript can be a lot more complicated than it seems. The obtained values ​​do not always fall within the expected ranges; sometimes the result may not be at all what we expected.

Math.abs()

The Math.abs() method returns the absolute value of a number, which reminds us of a similar mathematical function for the modulus of a number.

Let newVal = -57.64; Math.abs(newVal); > 57.64
Math.abs(0) always returns zero, but if we put a minus sign in front of the -Math.abs(NUM) function we will always get a negative value.

Math.abs(0); > -0

parseInt()

We know that JavaScript understands that “15” is a string, not a number, and, for example, when parsing CSS properties using JavaScript, or receiving a value from an unprepared array, our results can be unpredictable. We could receive a string represented as “17px” as input, and this is not uncommon for us. The question is how to convert this string into an actual value and use it in further calculations.

Syntax: parseInt(string, radix);

The parseInt function converts the first argument passed to it to a string type, interprets it, and returns an integer or NaN value. The result (if not NaN) is an integer and is the first argument (string), treated as a number in the specified radix. For example, base 10 indicates conversion from decimal, 8 from octal, 16 from hexadecimal, and so on. If the base is greater than 10, then letters are used to represent numbers greater than 9. For example, for hexadecimal numbers (base 16), the letters A through F are used.

Let's look at an example of working with CSS properties, where, relatively speaking, we can get the following value:

Let elem = document.body; let centerPoint = window.getComputedStyle(elem).transformOrigin; > "454px 2087.19px"
We can split the values ​​by spaces:

Let centers = centerPoint.split(" "); > ["454px", "2087.19px"]
However, each element is still a string, we can get rid of this by using our function:

Let centerX = parseInt(centers, 10); > 454 let centerY = parseInt(centers, 10); >2087
As you can see, with the second argument we indicate the number system into which the number will be converted; this parameter is optional, but it is recommended to use it if you do not know which string will be received as input.

parseFloat()

From the example above, you probably noticed that parseInt discards the fractional part. In our case, parseFloat can work with floating point numbers. Again, this can be useful when parsing CSS and other tasks, especially when working with floating point percentages.

Syntax: parseFloat(string)

Let FP = "33.33333%"; console.log(parseFloat(FP)); > 33.33333
Note that there is no second argument in the parseFloat syntax.

We understand that parseInt() and parseFloat() are extremely useful features, it is important to note that there are still some errors involved, so it is necessary to check the range of expected values ​​and ultimately analyze the result to ensure that the values ​​obtained are correct.
Send anonymously


In this part of our lessons we will get acquainted with the object Number as with a numeric data type container. Its actual objective essence will be touched upon very superficially today.

Same as object String contains lines of text, object Number contains numbers. Just like strings, numbers we create automatically become instances of an object.

Number data type

There are two types of numbers in JavaScript: integer and floating point (there are no divisions into many types, as in other languages ​​integer, long, short, double ). Floating-point numbers have integer and fractional parts separated by a dot (regardless of locale settings).

These two types of numbers are not independent types and do not require special conversion between themselves. If, for example, 32.5 we will multiply by 0.4 , then we immediately get an integer 13 , not a fraction 13.0 , which needs to be converted to an integer value (as is often the case in other languages).

Creating a Number object

Like a string, a number is usually instantiated as an object Number, a simple assignment (unlike a string, no quotes are required).

var myNum = 21 ;

But you can also create new object using the constructor:

var myNum = new Number; myNum = 21 ;

In the vast majority of cases, this is unnecessary and even harmful. We will look at correct examples of such work with objects in Part 4.

Number representation

Exponential form

Numbers can be represented in either ordinary or exponential form, for example:

2e6 // no spaces!

It means: 2 × 10 6

If we output such a number through the document method write(), then we get an expanded number in the usual representation.

Document. write(14e12);

Result:

Basic number systems

Numbers can also be represented in decimal, hexadecimal, and octal systems.

Whole numbers in decimal form shouldn't start from scratch, because zero is a prefix for non-decimal systems. Just 0 prefix for octal values, and 0x for hexadecimal.

For example, 075 is the octal representation of a decimal number 61 , A 0x75 hexadecimal representation of decimal number 117 .

For octal values, the numbers from 0 before 7 , for hexadecimal alphanumeric series 0123456789ABCDEF. Letters can be used in any register.

Arithmetic expressions can use any form of numbers, but the result will always be represented as a decimal number.

Representation of numbers in other systems

Speaking about the object String, we touched on the method toString(), which converts any object to a string. When converting numbers to strings, it is advisable to specify the number system as an argument.

note

The original number must be enclosed in brackets

(number). toString(system)

system can take any value from 2 to 36.

(157 ).toString(2 ); // binary representation 157, equals (53 ).toString(27 ); // exotic 27-digit representation 53, equals

But these resulting expressions are strings. To make them real numbers in specified systems calculus, you need the result of the method toString(system) convert back to number. This is no longer done by method, but kernel function Number(object). We will talk about kernel functions in one of the upcoming lessons, but for now pay attention to the syntax, it is similar to a function call:

var a = 1546 ; var b = a. toString(2); var c = Number(b);

Or immediately, “two in one”:

var a = 1546 ; var b = Number(a. toString(2 ));

Note

If the original number is assigned to a variable, then it does not need to be placed in parentheses when calling the method toString() .

Properties of the Number object

We will touch on the general object properties of constructor and prototype in the lesson about the object Object, and now let’s turn to the specific properties of the object Number.

These properties only for reading, that is, we cannot change them.

MAX_VALUE

The maximum number that can be processed in JavaScript.

Let's see what kind of number this is:

var e = Number . MAX_VALUE document. write(e)

Result:

1.7976931348623157e+308

Plus in this case is not an addition sign, but a positive degree, that is 1.7976931348623157 × 10,308

Note

I usually demonstrate results using actually written scripts. But too many fractional calculations can slow down page loading, and most of the results in this tutorial are handwritten, so to speak.

MIN_VALUE

And this is accordingly the minimum value. Let's explore it.

var f = Number . MIN_VALUE document. write(f)

Result:

That is 5 × 10 -324

A non-numeric value that we have already encountered.

This property is returned by JavaScript when a numeric operation somehow produces a non-numeric result.

NEGATIVE_INFINITY, POSITIVE_INFINITY

Once upon a time they thought something like this: “one deer, two deer, many deer.”

JavaScript counts a little more "advanced": "one deer, two deer, three deer, ..., 1.7976931348623157 × 10,308 deer, many deer."

This transcendental “many” is expressed by the property POSITIVE_INFINITY.

At reverse process dividing a unit (“one deer”) into small, small pieces the smallest piece counted will be 5 × 10 -324 part. Anything less is already NEGATIVE_INFINITY.

Methods of the Number object

Note: Just like the toString() method, all other methods require the original number to be enclosed in parentheses if it is represented explicitly (rather than as a variable).

toExponential()

Returns a string representing a number in scientific notation, with one digit before the decimal point.

Syntax:

number. toExponential(number of signs)

Argument number of signs specifies the rounding precision after the decimal point. If the argument is omitted, the number of digits after the decimal point is equal to the number of digits needed to represent the value.

Example:

var myFullNumber = 4659872156831598853654127 ; document. write(myFullNumber.toExponential(4))

Result:

toFixed()

Returns a string representing a fixed-point number, rounded to the number of decimal places specified in the argument.

Syntax:

number. toFixed(number of signs)

Examples:

var myDecimal1 = 46.59872156831598853654127 ; var myDecimal2 = 46 ; document. write(myDecimal1.toFixed(1)) document. write("
") document. write(myDecimal2.toFixed(3))

Results:

This method is sometimes very useful. For example, the cumbersome function from the last lesson can now be represented like this:

function anyRootPlus(x, y) ( var srcnum = Math . exp(Math. log(x)/y); var result = (srcnum). toFixed(3); return result; )

Now let’s insert it into the form and test it:

True, now integers will also have three zeros after the dot. But, knowing the behavior of numbers and strings, knowing how to work with conditional operators and type conversion, it is not so difficult to make the necessary numerical “design”.

toLocaleString()

Converts a numeric object to a string value, taking into account locale settings for decimal separators and thousands separators. The national currency is taken as the basis, therefore in the Russian version all numbers, even integers, are presented with two decimal places (kopecks):

var myDrob = 25.327 ; var myMnogo = 25635120 ; var myRoubl = 35 ; /* make it larger to see the commas better */ document. write("

" + myDrob. toLocaleString() + "

" ); document. write("

" + myMnogo. toLocaleString() + "

" ); document. write("

" + myRoubl. toLocaleString() + "

" );

Results:

toPrecision()

Returns a string representing a number with the specified total number of significant digits.

Syntax:

number. toPrecision(quantityDigits)

Argument:

quantityDigits number of digits in the displayed line. If the specified quantity is greater than the quantity in the original number, decimal zeros are displayed.

Document. write((354 ).toPrecision(8 ))

Result:

Methods toPrecision() And toLocaleString() together does not work, for “Russian design” numbers of any precision will need to be written own function. The written function can be made an additional method of the object Number, we have already done something similar with the object Date(). More details in the lesson about the object Object.

toString()

Well, we already discussed this method in detail at the beginning of the lesson.

Create your own method

Now we will create the same method that will display a number with any number of decimal places with spaces between the thousandth places and with a comma as a decimal separator.

To do this, we need a rather tricky function that will convert strings and arrays obtained from an instance of an object Number.

Let's declare the method:

Number.prototype.toRussianString = toRussianString

Before we start building the function, let's formulate the tasks.

First we need to represent the number as a string and extract the integer part, fractional part and separator point from it.

Then place the necessary spaces in the integer part, round the fractional part to the number of characters that can be specified as an argument to the function (and method), and change the period to a comma.

Let's start the function by declaring the necessary variables.

function toRussianString(prec) ( /* variables for converting strings */ var a = "" , b = "" , c, d, e;

Looking ahead, I will say that the decimal part, as a result of our string perturbations, loses its “fractional” essence, and we have to work with it as with another integer. To work with it we will use the method toPrecision(), and the argument of our function (and at the same time of our method) sets the value specifically for the method toPrecision(). The minimum parameter of this method is one. And our function may also need zero (when rounding to an integer). And at the same time, correct rounding should work even before we begin to “dismember” the object. Therefore, immediately when declaring variables, we will bypass this pitfall:

/* a variable that converts a given object instance to a string */ if (prec == 0 ) var str = this . toFixed(0 ).toStringtoString(10 );

We continue declaring variables.

/* variable for return value */ var nr1; /* variables for parts of the “explosion” */ var intpart, fractpaft, precpart, divider, dot = str. lastIndexOf("." ); /* counter */ var i;

Variable dot finds the position of a point in a string of the specified number. At this position we cut off the whole part ( intpart). If the number is an integer and there is no point, its position will be less than zero. In this case, the separator ( divider), and the fractional part ( fractpart) must be empty strings. Otherwise, a comma is assigned to the separator, and the fractional part is cut off for further work:

if (dot< 0 ) { intpart = str; fractpart = "" ; divider = "" ;) else (intpart = str. substring(0 , dot); fractpart = str. substring(dot + 1 , str. length); divider = "," ;}

We work with the whole part. Spaces are only needed if there are more than 3 characters:

if(intpart. length > 3 ) {

Now let’s play the following “solitaire” game (all this happens inside a conditional statement):

Let's cycle through the triplets in reverse order.

First, let's collect them into a variable a without any additions, just to calculate the length of the resulting substring. After all, if the total number of digits was not divisible by 3, then a tail of 1 or 2 digits remained on the left, and now we can express it as a substring by subtracting the length of the substring with “threes” from the length of the entire string (variable c). And put a non-breaking space in front of it (which we will remove later). For what? Since groups of three digits were read in reverse order, this initial tail should be placed at the end of the row. That is, if we had a number, say, 36748521, we need to line up 521,748 36, putting a non-breaking space in front of each group so that there is a separator for the array (after all, we need to flip them back, and this can be done using the array method reverse()).

In the last instruction of the loop, we will arrange in triplets and write the result to a variable b.

for (i=intpart. length-3 ; i>=0 ; i-=3 ) /* collect triplets */( a = a + intpart. substr(i, 3); /* find the left “tail” */ c = " " + intpart. substr(0 , intpart. length-a. length); /* place separators in triplets */ b = b + " " + intpart. substr(i, 3);)

When adding strings b+c we get a string that needs to be converted into an array, and then this array is reversed and converted back into a string (this is all written to a variable d).

D = (b+c). split(" " ).reverse().toString().replace(/,/g, " " );

The array is converted to a string along with comma delimiters; we don't need them. Therefore, in the same instructions we remove them using regular expression /,/g, Where /,/ creating a regular expression for the comma, and g“flag”, which indicates that you need to replace all patterns of expression (simply put all commas) that appear in the line. We replace them with the same non-breaking spaces.

(Details about regular expressions will be discussed in the last part of the manual.)

And now we need to clean up something else (inside the same conditional statement if (intpart.length > 3)).

The fact is that either at the beginning or at the end of our line there will be an extra non-breaking space consisting of 6 characters: “&”, “n”, “b”, “s”, “p” and “;”. Therefore, let's clear the garbage and write the result to a variable e:

if(d. substring(0 , 1 ) == "&" ) e = d. substring(6 , d. length-6 ); else e = d. substring(0 , d. length-6 );

Now we can, with a clear conscience, close the entire conditional operator and write Alternative option for a short number that does not need to be divided into “threes”.

) else e = intpart;

So the variable e stores the integer part of the number, and we will deal with the decimal part.

Attention! When we work with fractional part(which must now be treated as a whole), we must remember that when prec == 0 the function will struggle, so let’s immediately plug it in:

if (prec != 0 ) (

Now you can work in peace. But there are a few more “stones” that we will now bypass.

Firstly, if we have a fractional part, suppose 41 , and we set rounding to 3 digits, then the method toPrecision, taking our fractional part as an integer, will output 41.0 , that is, you need to remove the point.

Secondly, if the fractional part of the original number is more than 3 digits, then the method toPrecision will begin to produce the result in exponential form. You will have to fight this too.

Therefore, we will “clean” the result through three variables: precpart, precpart1 And precpart2.

Precpart = (Number (fractpart). toPrecision(prec)). toString(10 )

Now we “clean”:

/* if there is a fractional part */ if (fractpart != "") ( /* look for and eliminate the point */ precpart1 = precpart. replace(".", "") /* check to see if there is an exponent there, */ var plus = precpart1.lastIndexOf("e"); /* and if it exists, */ if (plus > 0 ) /* pull it out by the roots, */ precpart2 = precpart1. substring(0 , plus); /* otherwise */ else /* don't change anything */ precpart2 = precpart1 ) /* if there is no fractional part, */ else /* then we output zeros and again get rid of the dot */ precpart2 = "," +precpart. replace("." , "" )

Since we indicated at the beginning that if there is no fractional part in the original number, there is no comma, then in this case we need to put it again.

) else ( /* that is, if prec is still zero, just print empty lines */ precpart2 = "" ; divider = "" ; }

And the final chord:

Nr1 = e + divider + precpart2; return nr1; )

The entire function:

function toRussianString(prec) ( var a = "" , b = "" , c, d, e; if (prec == 0 ) var str = this . toFixed(0 ).toString(10 ); else var str = this . toString(10 ); var nr1; var intpart, fractpaft, precpart, divider, dot = str. lastIndexOf("." ); var i; if (dot< 0 ) { intpart = str; fractpart = "" ; divider = "" ;) else (intpart = str. substring(0 , dot); fractpart = str. substring(dot + 1 , str. length); divider = "," ;) if (intpart. length> 3 ) ( for (i=intpart. length-3 ; i>=0 ; i-=3 ) ( a = a + intpart. substr(i, 3); c = " " + intpart. substr(0 , intpart. length-a. length); b = b + " " + intpart. substr(i, 3 );) d = (b+c). split(" " ).reverse().toString().replace(/,/g, " " ); if(d. substring(0 , 1 ) == "&" ) e = d. substring(6 , d. length-6 ); else e = d. substring(0 , d. length-6 ); ) else e = intpart; if (prec != 0 ) ( precpart = (Number (fractpart). toPrecision(prec)). toString(10) if (fractpart != "") ( precpart1 = precpart. replace(".", "") var plus = precpart1.lastIndexOf("e"); if (plus > 0 ) precpart2 = precpart1. substring(0 , plus); else precpart2 = precpart1 ) else precpart2 = "," +precpart. replace("." , "" ) ) else ( precpart2 = "" ; divider = "" ; ) nr1 = e + divider + precpart2; return nr1; )

This function can now be called as a method.

Var myNumber = 2569843359.6583521 document. write(myNumber. toRussianString(3 ))

Result:

You can place the method constructor and function in a library - that is, in a .js file that can be called from web page code. As you write methods for different objects, you can sort the methods into library files for these objects and use additional methods.

This allows you to fix @MarkElliot's answer so that it works for negative numbers as well:

Var div = Math.trunc(y/x); var rem = y % x;

Note that the Math methods have the advantage over bitwise operators that they work with numbers greater than 2 31 .

JavaScript calculates on the right the gender of negative numbers and the remainder of non-integers, following the mathematical definitions for them.

FLOOR is defined as "the largest integer less than the parameter", thus:

  • positive numbers: FLOOR(X) = integer part of X;
  • negative numbers: FLOOR(X) = integer part of X minus 1 (because it should be SMALLER than the parameter, i.e. more negative!)

REMAINDER is defined as the "remaining" divisions (Euclidean arithmetic). When the dividend is not an integer, the factor is usually also not an integer, i.e. there is no remainder, but if the factor is forced to be an integer (and this is what happens when someone tries to get the remainder or modulus of a floating point number ), obviously there will be an integer “left”.

JavaScript calculates everything as expected, so the programmer must be careful to ask the right questions (and people must be careful to answer what is asked!) Yarin's first question was NOT "what is integer division of X by Y", instead this: "The integer number of times a given integer GOES TO another." For positive numbers, the answer is the same for both, but not for negative numbers, because integer division (dividend by divisor) will be -1 less than the number (divisor) "rolls over" (dividend). In other words, FLOOR will return the correct answer for integer division of a negative number, but Yarin didn't ask about that!

gammax answered correctly, this code works according to Yarin's instructions. On the other hand, Samuel is wrong, he didn't do the math I guess, or he would have seen that this actually works (also he didn't say what the divisor of his example was, but I hope it was 3):

Remainder = X% Y = -100% 3 = -1

GoesInto = (X - Remainder) / Y = (-100 - -1) / 3 = -99 / 3 = -33

By the way, I tested the code on Firefox 27.0.1, it worked as expected with positive and negative numbers, as well as non-integer values, for both dividends and divisors. Example:

100.34 / 3.57: GoesInto = -28, Remainder = -0.3800000000000079

Yes, I noticed that there is a problem with high precision, but I haven't had time to check it (I don't know if it's a problem with Firefox, Windows 7, or my CPU's FPU). However, for Yarin's question, which only involves integers, the gammax code works fine.

You can use the parseInt function to get the truncated result.

ParseInt(a/b)

To get the remainder, use the mod operator:

parseInt has some pitfalls with strings to avoid using the radix parameter with base 10

ParseInt("09", 10)

In some cases, the string representation of a number may be scientific notation, in which case parseInt will produce an incorrect result.

ParseInt(1000000000000000000000000000000000, 10) // 1e+32

This call will produce result 1.

Calculating the number of pages can be done in one step: Math.ceil(x/y)

If you're just sharing the powers of two, you can use bitwise operators:

Export function divideBy2(num) ( return ; ) export function divideBy4(num) ( return ; ) export function divideBy8(num) ( return ; )

(The first is the particular, the second is the rest)

This will always truncate to zero. Not sure if it's too late, but it says here:

Function intdiv(dividend, divisor) ( divisor = divisor - divisor % 1; if (divisor == 0) throw new Error("division by zero"); dividend = dividend - dividend % 1; var rem = dividend % divisor; return ( remainder: rem, quotient: (dividend - rem) / divisor ); )

I'm not an expert in bitwise operators, but here's another way to get an integer:

Var num = ~~(a / b);

This will work fine for negative numbers as well, while Math.floor() will rotate in the wrong direction.

This also seems correct:

Var num = (a / b) >> 0;

Math.floor(operation) returns the rounded value of the operation.

Example of question 1:

Var x = 5; var y = 10.4; var z = Math.floor(x + y); console.log(z);

Console:

Example of question 2:

Var x = 14; var y = 5; var z = Math.floor(x%y); console.log(x);

Console:

For some number y and some divisor x, calculate the quotient and remainder (remainder) as:

Var quotient = Math.floor(y/x); var remainder = y % x;

In this article we will look in detail at numbers, mathematical operators, ways to convert a number into a string and vice versa, as well as many other important points.

isFinite function

The isFinite function allows you to check whether an argument is a finite number.

As an answer this function returns false if the argument is Infinity , -Infinity , NaN , or will be cast to one of these special numeric values. Otherwise, this function will return true.

IsFinite(73); // true isFinite(-1/0); // false isFinite(Infinity); // false isFinite(NaN); // false isFinite("Text"); // false

In addition to the global isFinite function, JavaScript also has the Number.isFinite method. Unlike isFinite, it does not force the argument to be converted to a number.

IsFinite("73"); // true Number.isFinite("73"); // false

isNaN function

The isNaN function is designed to determine whether an argument is a number or can be converted to one. If so, then the isNaN function returns false. Otherwise it returns true.

IsNaN(NaN); //true isNaN("25px"); //true, because 20px is not a number isNaN(25.5); //false isNaN("25.5"); //false isNaN(" "); //false, because a space or several spaces is converted to 0 isNaN(null); //false, because null is converted to 0 isNaN(true); //false, because true is converted to 1 isNaN(false); //false, because value false converted to 0

If this action needs to be performed without a type cast, then use the Number.isNaN method. This method was introduced into the language starting with ECMAScript 6.

How to explicitly convert a string to a number?

You can explicitly convert a string to a number using the following methods:

1. Use unary operator +, which must be placed before the value.

+"7.35"; // 7.35 +"text"; // NaN

This method ignores spaces at the beginning and end of the line, as well as \n (line feed).

+" 7.35 "; //7.35 +"7.35 \n "; //7.35

Using this method Note that an empty string or a string consisting of spaces and \n is converted to the number 0. In addition, it also converts the null data type and boolean values ​​to a number.

Null; //0 +true; //1 +false; //0 +" "; //0

2. ParseInt function. This function is designed to convert argument to integer. Unlike using unary operator +, this method allows you to convert a string to a number, in which not all characters are numeric. It begins to convert the string, starting from the first character. And as soon as it encounters a non-numeric character, this function stops its work and returns the resulting number.

ParseInt("18px"); //18 parseInt("33.3%"); //33

This function can work with different systems Numbers (binary, octal, decimal, hexadecimal). The base of the number system is specified using 2 arguments.

ParseInt("18px", 10); //18 parseInt("33.3%", 10); //33 parseInt("101",2); //5 parseInt("B5",16); //181

In addition to the parseInt function, JavaScript has the Number.parseInt method. This method is no different from the parseInt function and was introduced into JavaScript with the ECMASCRIPT 2015 (6) specification.

3. parseFloat function. The parseFloat function is similar to parseInt , except that it allows you to convert the argument to a fractional number.

ParseFloat("33.3%"); //33.3

In addition, the parseFloat function, unlike parseInt, does not have 2 arguments, and therefore it always tries to treat the string as a number in the decimal notation system.

ParseFloat("3.14"); parseFloat("314e-2"); parseFloat("0.0314E+2");

In addition to the parseFloat function, JavaScript has the Number.parseFloat method. This method is no different from the parseFloat function and was introduced into JavaScript with the ECMASCRIPT 2015 (6) specification.

Converting a number to a string

You can turn a number into a string using the toString method.

(12.8).toString(); //"12.8"

The toString method also allows you to specify the base of the number system, taking into account which you need to explicitly convert the number to a string:

(255).toString(16); //"ff"

How to check if a variable is a number

You can determine whether the value of a variable is a number using one of the following methods:

1. Using the isNaN and isFinite functions:

// myVar is a variable if (!isNaN(parseFloat(myVar)) && isFinite(parseFloat(myVar))) ( //myVar is a number or can be cast to it);

As a function:

// function function isNumeric(value) ( ​​return !isNaN(parseFloat(value)) && isFinite(parseFloat(value)); ) // use var myVar = "12px"; console.log(isNumeric(myVar)); //true

This method allows you to determine whether the specified value is a number or can be converted to one. This option does not count the empty string, string of spaces, null, Infinity, -Infinity, true and false as a number.

2. Using the typeof operator and the isFinite, isNaN functions:

// function that checks whether the value is a number function isNumber(value) ( ​​return typeof value === "number" && isFinite(value) && !isNaN(value); }; // использование функции isNumber isNumber(18); //true // использование функций для проверки текстовых значений isNumber(parseFloat("")); //false isNumber(parseFloat("Infinity")); //false isNumber(parseFloat("12px")); //true !}

This function determines whether the specified value is of type Number and whether it is one of the special values ​​Infinity, -Infinity, and NaN. If so, then this function returns true.

3. Using the ECMAScript 6 Number.isInteger(value) method. This method allows you to determine whether the specified value is an integer.

Number.isInteger("20"); //false, because this method does not convert a string to a number Number.isInteger(20); //true, because given value is a number

Even and odd numbers

You can check whether a number is even or odd using following functions:

// Function for checking a number for even parity function isEven(n) ( return n % 2 == 0; ) // Function for checking a number for odd parity function isOdd(n) ( return Math.abs(n % 2) == 1; )

But before carrying out such a check, it is advisable to make sure that the specified value is a number:

Value = 20; if (Number.isInteger(value)) ( if (isEven(value)) ( console.log("Number " + value.toString() + " - even"); ) )

Prime numbers in Javascript

Let's look at an example in which we derive from using Javascript prime numbers from 2 to 100.

// Function that checks whether a number is prime function isPrime(value) ( ​​if (isNaN(value) || !isFinite(value) || value%1 || value< 2) return false; var max=Math.floor(Math.sqrt(value)); for (var i = 2; i< = max; i++) { if (value%i==0) { return false; } } return true; } // создать массив, который будет содержать простые числа от 2 до 100 var primaryNumber = ; for (var i = 2; i <= 100; i++) { if(isPrime(i)) primaryNumber.push(i); } // вывести в консоль простые числа от 2 до 100 console.log(primaryNumber);

Rounding a number in Javascript

There are various ways to round a fraction to a whole number in JavaScript.

1. Using the Math.floor, Math.ceil and Math.round methods specially designed for this. The Math.floor method rounds a fraction down to the nearest integer, i.e. simply discards the fractional part. Math.ceil rounds a fraction up to the nearest whole number. Math.round rounds a number up or down depending on the value of the fractional part. If the fractional part is greater than or equal to 0.5, then up, otherwise the twist is down.

Console.log(Math.floor(7.9)); //7 console.log(Math.ceil(7.2)); //8 console.log(Math.round(7.5)); //8

2. Using the toFixed(precision) method. This method rounds the fractional part of a number to a specified precision. The rounding result is returned as a string.

Console.log(7.987.toFixed(2)); //"7.99"

If there are not enough decimal places to form the specified precision of the number, then it is padded with zeros.

Console.log(7.987.toFixed(5)); //"7.98700"

3. Using the toPrecision(accuracy) method. This method represents a number with a specified precision. At the same time, he can round not only the fractional, but also the whole part of the number. Depending on the result, this method can present the resulting number with a fixed point or in exponential form.

Console.log((1001).toPrecision(2)); //"1.0e+3" console.log((1001).toPrecision(5)); //"1001.0" console.log((12.4).toPrecision(1)); //"1e+1" console.log((12.4).toPrecision(2)); //"12" console.log((12.4).toPrecision(3)); //"12.4" console.log((12.4).toPrecision(5)); //"12.400"

4. Using the logical operators NOT or OR.

//via double logical negation console.log(~~7.9); //7 // by using logical OR with zero: console.log(7.9^0); //7

Integer and fractional part of a number

You can get the integer part of a number using the Math.floor() and parseInt() methods:

Console.log(Math.floor(7.21)); // 7 console.log(parseInt(7.21)); // 7

You can get the fractional part of a number using the percentage (%) operator. This operator returns the remainder that will be obtained from dividing the first number by the second. In this case, you must use 1 as the 2nd number.

Console.log(7.21%1); // 0.20999999999999996 // accurate to 2 decimal places console.log((7.21%1).toFixed(2)); // "0.21"

In addition, the fractional part can also be obtained using calculations:

Var number = 7.21; var fractionNumber = number - Math.floor(Math.abs(number)); console.log(fractionNumber); // 0.20999999999999996

Is the number divisible by an integer?

You can determine whether a number is divisible by an integer using the percentage operator:

Var number = 9; // if the remainder of number divided by 3 is 0, then yes, otherwise no if (number%3==0) ( console.log ("The number " + number + " is divisible by 3"); ) else ( console. log("The number " + number + " is not divisible by 3"); )

Formatting numbers

In JavaScript, the toLocaleString() method allows you to format the output of a number in accordance with regional standards (language settings of the operating system).

For example, let's format a number in accordance with the regional standards that are installed in the system by default:

Var number = 345.46; console.log(number.toLocaleString()); //"345.46"

For example, let's format the number in accordance with the regional standards of Russia (ru):

Console.log((108.1).toLocaleString("ru-RU")); //"108.1"

This method can also be used to format a number as a currency:

Console.log((2540.125).toLocaleString("ru-RU",(style:"currency", currency:"RUB"))); //"2,540.13 ₽" console.log((89.3).toLocaleString("ru-RU",(style:"currency", currency:"USD"))); //"89.30 $" console.log((2301.99).toLocaleString("ru-RU",(style:"currency", currency:"EUR"))); //"€2,301.99"

Representing a number as a percentage:

Console.log((0.45).toLocaleString("ru-RU",(style:"percent"))); //"45%"

Break a number into digits (useGrouping property):

Console.log((125452.32).toLocaleString("ru-RU",(useGrouping:true))); //"125,452.32"

Print a number with a certain number of digits (2) after the decimal point:

Console.log((1240.4564).toLocaleString("ru-RU",(minimumFractionDigits:2, maximumFractionDigits:2))); //"1,240.46"

Comparison of numbers

The following operators are used to compare numbers in JavaScript: == (equal), != (not equal), > (greater than),< (меньше), >= (greater than or equal to),<= (меньше или равно).

For example, let's compare two numbers:

Console.log(2>3); //false console.log(5>=3); //true

When comparing numbers with a fractional part, it is necessary to take into account the errors that may arise during these calculations.

For example, in JavaScript the sum of the numbers (0.2 + 0.4) does not equal 0.6:

Console.log((0.2+0.4)==0.6); //false

Errors occur because all calculations are made by computer or other electronic device produces in 2 number system. Those. Before performing any actions, the computer must first convert the numbers presented in the expression to the 2nd number system. But not every fractional decimal number can be represented exactly in the 2nd number system.

For example, the number 0.25 10 is converted into binary exactly.

0.125 × 2 = 0.25 | 0 0.25 × 2 = 0.5 | 0 0.5 × 2 = 1 | 1 0.125 10 = 0.001 2

For example, the number 0.2 10 can be converted into the 2 system only with a certain accuracy:

0.2 × 2 = 0.4 | 0 0.4 × 2 = 0.8 | 0 0.8 × 2 = 1.6 | 1 0.6 × 2 = 1.2 | 1 0.2 × 2 = 0.4 | 0 0.4 × 2 = 0.8 | 0 0.8 × 2 = 1.6 | 1 0.6 × 2 = 1.2 | 1 0.2 × 2 = 0.4 | 0 0.4 × 2 = 0.8 | 0 0.8 × 2 = 1.6 | 1 0.6 × 2 = 1.2 | 1 ... 0.2 10 = 0.001100110011... 2

As a result, these errors will affect the calculation of the sum of two numbers and the comparison results. Those. It turns out that JavaScript will actually see this entry as follows:

0.6000000000000001==0.6

When calculating or displaying numbers with fractional parts, you must always indicate the precision with which you want to do so.

For example, compare numbers up to 2 decimal places using the toFixed() and toPrecision() methods:

//method toFixed() console.log((0.2+0.4).toFixed(2)==(0.6).toFixed(2)); //true //method toPrecision() console.log((0.2+0.4).toPrecision(2)==(0.6).toPrecision(2)); //true

Basic Math Operations

The following mathematical operators exist in JavaScript: + (addition), - (subtraction), * (multiplication), / (division), % (modulo), ++ (increase a value by 1), -- (decrease a value by 1 ).

6+3 //9 6-3 //3 6*3 //18 6/3 //2 6%3 //0, i.e. 6:3=2 => 6-3*2 => rest(0) 5%2 //1, i.e. 5:2=2(.5) => 5-2*2 => rest(1) 7.3%2 //1.3, i.e. 7.3:2=3(.65) => 7.3-2*3 => rest(1.3) //the sign of the result of the % operation is equal to the sign of the first value -9%2.5 //-1.5, i.e. 9:2.5=3(.6) => 9-2.5*3 => rest(1.5) -9%-2.5 //-1.5, i.e. 9:2.5=3(.6) => 9-2.5*3 => rest(1.5) -2%5 //-2, i.e. 2:5=0(.4) => 2-5*0 => rest(2) x = 3; console.log(x++); //outputs 3, then sets 4 console.log(x); //4 x = 3; console.log(++x); //sets 4 and outputs x = 5; console.log(x--); //outputs 5, then sets 4 console.log(x); //4 x = 5; console.log(--x); //sets 4 and outputs In addition, JavaScript has combination operators: x+=y (x=x+y), x-=y (x=x-y), x*=y (x=x*y), x/= y (x=x/y), x%=y (x=x%y). x = 3; y = 6; x+=y; console.log(x); //9 x = 3; y = 6; x-=y; console.log(x); //-3 x = 3; y = 6; x*=y; console.log(x); //18 x = 3; y = 6; x/=y; console.log(x); //0.5 x = 3; y = 6; x%=y; console.log(x); //3

Often calculations produce results that are outside the desired ranges. As a result, it is necessary to implement JavaScript rounding up to a certain value.

Why round numbers?

JavaScript does not store integers because their values ​​are represented as floating point numbers. Many fractions cannot be represented as a number with a specific finite number of decimal places, so JavaScript can generate results like the following:

0.1 * 0.2; > 0.020000000000000004

In practice, this will not make any difference, since we are talking about an error of 2 quintillionths. But this may affect the results when working with numbers that represent currency values, percentages, or file size. Therefore, you need to do or to a certain decimal place.

Rounding decimal numbers

To "cut" a decimal number, use the toFixed() or toPrecision() methods. They both take one argument, which specifies the number of significant and decimal places to be included in the result:

  • if toFixed() has no argument specified, the default value is 0 , that is, no decimal places; the maximum argument value is 20 ;
  • if no argument is given to toPrecision(), the number is not changed.

var randNum = 6.25; randNum.toFixed(); > "6" Math.PI.toPrecision(1); > "3" var randNum = 87.335; randNum.toFixed(2); > "87.33" var randNum = 87.337; randNum.toPrecision(3); > "87.3"

Note

Both toFixed() and toPrecision return a rounded string representation of the result, rather than a number. This means that adding rounded to randNum will result in a concatenation of strings rather than a single number:

console.log(randNum + rounded); > "6.256"

If you want JavaScript to round a number to the nearest hundredth, use parseFloat() :

var randNum = 6.25; var rounded = parseFloat(randNum.toFixed(1)); console.log(rounded); > 6.3

toFixed() and toPrecision() are also useful methods for truncating large numbers of decimal places. This is useful when working with numbers representing monetary units:

var wholeNum = 1 var dollarsCents = wholeNum.toFixed(2); console.log(dollarsCents); > "1.00"

Note that if a number has more digits than the precision specified, toPrecision will output the result in scientific format:

var num = 123.435 num.toPrecision(2); > "1.2e+2"

How to avoid mistakes when rounding decimals

In some cases toFixed and toPrecision implement JavaScript rounding 5 down, and not to more:

var numTest = 1.005; numTest.toFixed(2); > 1;

The result of the above example should be 1.01, not 1. If you want to avoid this error, I recommend using exponential numbers:

function round(value, decimals) ( return Number(Math.round(value+"e"+decimals)+"e-"+decimals); )

Application:

round(1.005,2); > 1.01

If you need an even more robust solution than rounding, it is available at MDN.

Rounding with epsilon

Alternative method JavaScript rounding to tenths was introduced in ES6 ( also known as JavaScript 2015). « Machine epsilon" provides a reasonable margin of error when comparing two floating point numbers. Without rounding, comparisons may produce results similar to the following:

0.1 + 0.2 === 0.3 > false

Math.EPSILON can be used in a function to get a valid comparison:

function epsEqu(x, y) ( return Math.abs(x - y)< Number.EPSILON * Math.max(Math.abs(x), Math.abs(y)); }

The function takes two arguments: one contains the calculations, the second the expected (rounded) result. It returns a comparison of these two parameters:

epsEqu(0.1 + 0.2, 0.3) > true

All modern browsers support ES6 math functions. But if you need to provide support in older browsers, then you need to use polyfills.

Truncation of decimal numbers

All methods presented previously perform JavaScript rounding to tenths. To truncate a positive number to two decimal places, multiply it by 100, truncate it again, and then divide the result by 100:

function truncated(num) ( return Math.trunc(num * 100) / 100; ) truncated(3.1416) > 3.14

If you need something more flexible, you can use the bitwise operator:

function truncated(num, decimalPlaces) ( var numPowerConverter = Math.pow(10, decimalPlaces); return ~~(num * numPowerConverter)/numPowerConverter; )

Usage:

var randInt = 35.874993; truncated(randInt,3); > 35.874

Round to the nearest number

To implement JavaScript rounding to the nearest integer, Math.round() is used:

Math.round(4.3) > 4 Math.round(4.5) > 5

Note that " half values", such as .5, are rounded up.

Round down to the nearest whole number

If you want to round down, use the Math.floor() method:

Math.floor(42.23); > 42 Math.floor(36.93); > 36

Rounding down has one direction for all numbers, including negative ones. This can be imagined as a skyscraper with an infinite number of floors, including below the foundation level ( representing negative numbers). If you are in the elevator between basement floors 2 and 3 ( which corresponds to a value of -2.5), Math.floor will take you to floor -3:

Math.floor(-2.5); > -3

If you need to avoid this, use JavaScript Math rounding using Math.trunc() , supported in all modern browsers (except IE/Edge):

Math.trunc(-41.43); > -41

MDN also provides three-line polyfill to provide support for Math.trunc in older browsers and IE/Edge.

Round up to the nearest whole number

If you want to round decimal numbers up, use Math.ceil . This method can also be thought of as an infinite elevator: Math.ceil always takes you “up”, regardless of whether the number is negative or positive:

Math.ceil(42.23); > 43 Math.ceil(36.93); > 37 Math.ceil(-36.93); -36

Round to the nearest multiple

If you need to round a value to the nearest multiple of 5, create a function that divides the number by 5, rounds it, and then multiplies the result by the same value:

function roundTo5(num) ( return Math.round(num/5)*5; )

Usage:

roundTo5(11); > 10

If you need JavaScript to round to two digits, you can pass both the seed and the multiple to the function:

function roundToMultiple(num, multiple) ( return Math.round(num/multiple)*multiple; )

To use the function, include the number to be rounded and the multiple in its call:

var initialNumber = 11; var multiple = 10; roundToMultiple(initialNumber, multiple); > 10;

To round values ​​up or down only, replace round with ceil or floor in the function.

Range binding

Sometimes you need to get a value for x that must be within a certain range. For example, we need a value from 1 to 100, but we get the value 123. To fix this you can use min() ( returns the smallest number) and max ( returns the maximum allowed number).

Usage:

var lowBound = 1; var highBound = 100; var numInput = 123; var clamped = Math.max(lowBound, Math.min(numInput, highBound)); console.log(clamped); > 100;

You can create a function or extension of the Number class.