Math object: Dealing w/ Decimals and the '~~' Operator
Tags: javascript, beginners
Published: 2022-10-09 23:25:46

Today during some reading I stumbled onto an ongoing debate among the coding community: what is the fastest way to convert _float_ (numbers with a decimal point) to an _integer_?

There are several different ways a programmer can handle this problem and I will go over a few of the simpler methods. 

Speaking of methods, let's talk about the built-in Javascript object 
`Math`.

```
console.log(Math.ceil(4.20));  // --> 5

console.log(Math.floor(6.9));  // --> 6

console.log(Math.round(5.5));  // --> 6

console.log(Math.trunc(1.337));// --> 1
```
Let me break down the above example: 

- `Math.ceil()` will round our float (decimal number) _up_ to the next highest whole (integer) value. Think ceiling // above.

- `Math.floor()` will round our float _down_ to the next lowest whole number. Think floor // below.

- `Math.round()` will use the most common arithmetic method of rounding up if decimal point is >= .5 or rounding down if <= .4.

- `Math.trunc` or _truncate_ will simply remove anything past the decimal point. 

But what if there was another way? Another, arguably, _faster_ way?
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iu1yo9cptbgdpvwtz1dz.jpg)

Introducing: `~~` or the **double-tilde** operator. 

```
console.log(~~13.12);           // --> 13

console.log(~~(-13.12));        // --> -13
```
The **double-tilde** operator behaves like a combination of our `Math` methods. A positive number will be rounded down while a negative number will be rounded up. This can be useful in some cases because a method like `Math.floor` may have undesired results when dealing with positive vs. negative numbers:

```
console.log(Math.floor(13.12)); // --> 13

console.log(Math.floor(-13.12));// --> -14
```
Above our positive number behaves as if it is rounded down while our negative number behaves almost as if it is rounded up (tricky because -14 is still "down" from -13)

Using `~~` is the equivalent of this function:

```
let doubleTilde = function(x) {
  if(x < 0) return Math.ceil(x);
  else return Math.floor(x);
}

doubleTilde = (x) => x < 0 ? Math.ceil(x) : Math.floor(x);
;^]
```
Applying the logic of `Math.ceil` for negative numbers and `Math.floor` for positive numbers. 

Hope this can be of use to you! (in some _very_ particular scenarios, but... oh well! happy coding!)

## Lagniappe

`~~` will coerce _ANY_ datatype to a number and will also extract a number from a single-element array:

```
console.log(~~"acab");   // --> 0

console.log(~~NaN);      // --> 0

console.log(~~null);     // --> 0

console.log(~~undefined);// --> 0

console.log(~~[69]);     // --> 69
```
Post-Script:
I didn't include every possible example but ~~ will even convert complex data types such as arrays ([]) and objects ({}) to a single number value (that value will === 0)...
It can even evaluate whole expressions or coerce the return value of a function to a single number value as well! Annnnnd, compared with `Math.trunc` I would argue its superiority because `Math.trunc` will return NaN for non-number / non-string data types. Try it in your code! <3

As I mentioned, Math.trunc versus bitwise operators is a contested debate among programmers and I encourage you to do your own reading/exploring/implementing of these ideas and find what works best for you. Here is a resource on bitwise operators and how the conversions/coercion with the double-tilde operator works... (it has to do with converting a decimal to a 32 bit/digit number which will remove all decimals anyway.. but that topic is far beyond my expertise):
https://stackoverflow.com/questions/38702724/math-floor-vs-math-trunc-javascript

And an image of the speed testing in the above link from user "Qwerty:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/et6xlb4hb50xt8m7ya6p.png)