# Numbers

## More ways to write a number

在實際使用大數字的時候，我們會用縮寫，像是 10 億會寫成 1bn，在程式裡也可以使用縮寫。

```javascript
let billion = 1e9;  // 1 billion, literally: 1 and 9 zeroes
alert( 7.3e9 );  // 7.3 billions (7,300,000,000)

1e3 = 1 * 1000
1.23e6 = 1.23 * 1000000

let ms = 0.000001;
let ms = 1e-6; // six zeroes to the left from 1

// -3 divides by 1 with 3 zeroes
1e-3 = 1 / 1000 (=0.001)

// -6 divides by 1 with 6 zeroes
1.23e-6 = 1.23 / 1000000 (=0.00000123)
```

### Hex, binary and octal numbers

hex 在 JavaScript 被廣泛應用，簡短的縮寫 0x + number 。

```javascript
alert( 0xff ); // 255
alert( 0xFF ); // 255 (the same, case doesn't matter)

let a = 0b11111111; // binary form of 255
let b = 0o377; // octal form of 255
alert( a == b ); // true, the same number 255 at both sides
```

## toString(base)

`num.toString(base)` 方法可以將 num 返回 string 用 base 數字系統。

* base = 16，16進位，返回 0-9 a-f。
* base = 2，2進位，返回 0-1。
* base = 36，36進位，返回 0-9 a-z。

```javascript
let num = 255;

alert( num.toString(16) );  // ff
alert( num.toString(2) );   // 11111111
```

### Two dots to call a method

如果要對數字直接使用方法要用 `..` 如果使用 `.` JavaScript 會認為使用小數點會造成錯誤。

```javascript
alert( 123456..toString(36) ); // 2n9c
alert( (123456).toString(36) ); // same 
```

## Rounding

* Math.floor：無條件退位
* Math.ceil：無條件進位
* Math.round：四捨五入
* &#x20;Math.trunc (not supported by Internet Explorer)：無條件捨去

|        | `Math.floor` | `Math.ceil` | `Math.round` | `Math.trunc` |
| ------ | ------------ | ----------- | ------------ | ------------ |
| `3.1`  | `3`          | `4`         | `3`          | `3`          |
| `3.6`  | `3`          | `4`         | `4`          | `3`          |
| `-1.1` | `-2`         | `-1`        | `-1`         | `-1`         |
| `-1.6` | `-2`         | `-1`        | `-2`         | `-1`         |

以上都是進位到整數的方法，若需要盡味道特定小數點後幾位，有 2 種方法：

1. Multiply-and-divide.

   ```javascript
   let num = 1.23456;

   alert( Math.floor(num * 100) / 100 ); // 1.23456 -> 123.456 -> 123 -> 1.23
   ```
2. `toFixed(n)` 方法四捨五入數字返回 string 在用 Number()、+返回數字。

   ```javascript
   let num = 12.34;
   alert( num.toFixed(1) ); // "12.3"

   let num = 12.36;
   alert( num.toFixed(1) ); // "12.4"

   let num = 12.34;
   alert( num.toFixed(5) ); // "12.34000", added zeroes to make exactly 5 digits
   ```

## Imprecise calculations

數字用 64-bit 系統儲存，52-bit 用來儲存數字，11-bit 儲存小數點，1-bit 儲存正負符號。

```javascript
// 數字太大
alert( 1e500 ); // Infinity

// 如同 10 進位 1/3 的運算無法整除，2 進位的系統也有無法整除的數字，造成不精確的小數位產生，其他語言也有相同情形。
alert( 0.1 + 0.2 == 0.3 ); // false
alert( 0.1 + 0.2 ); // 0.30000000000000004

// 解決的方法用 toFixed()
let sum = 0.1 + 0.2;
alert( +sum.toFixed(2) ); // 0.3

// 乘除運算可以降低錯誤但仍有錯誤產生
alert( (0.1 * 10 + 0.2 * 10) / 10 ); // 0.3
alert( (0.28 * 100 + 0.14 * 100) / 100); // 0.4200000000000001
```

### The funny thing

```javascript
// Hello! I'm a self-increasing number!
alert( 9999999999999999 ); // shows 10000000000000000

// 每個數字都有 1-bit 紀錄正負符號，因此有 +0 -0 產生，但這不影響計算。
```

## Tests: isFinite and isNaN

number 類型有 2 個特別的值 `Infinity` `NaN` 需要特別的方法檢測他們。

* `isNaN(value)` 轉換參數為 number 檢測是否為 NaN，返回布林值。

  ```javascript
  alert( isNaN(NaN) ); // true
  alert( isNaN("str") ); // true

  alert( NaN === NaN ); // false
  ```
* `isFinite(value)` 轉換參數為 number 檢測是否為 Infinity ，返回布林值。

  ```javascript
  alert( isFinite("15") ); // true
  alert( isFinite("str") ); // false, because a special value: NaN
  alert( isFinite(Infinity) ); // false, because a special value: Infinity

  let num = +prompt("Enter a number", '');
  // will be true unless you enter Infinity, -Infinity or not a number
  alert( isFinite(num) );
  ```

## parseInt and parseFloat

通常在類型轉換的時候數字後有單位，像是 '100px'、'12pt'，這時要使用 parseInt and parseFloat。

```javascript
// 一般的轉換無法忽略單位
alert( +"100px" ); // NaN

// parseInt and parseFloat 讀取數字直到非數字
alert( parseInt('100px') ); // 100
alert( parseFloat('12.5em') ); // 12.5

// parseInt 返回整數，paseFloat 返回小數
alert( parseInt('12.3') ); // 12, only the integer part is returned
alert( parseFloat('12.3.4') ); // 12.3, the second point stops the reading

// 一開始就是非數字無法讀取
alert( parseInt('a123') ); // NaN, the first symbol stops the process

// parseInt(str, radix) 第 2 個參數設定讀取的數字系統
alert( parseInt('0xff', 16) ); // 255
alert( parseInt('ff', 16) ); // 255, without 0x also works

alert( parseInt('2n9c', 36) ); // 123456
```

## Other math functions

* `Math.random()` 隨機產生介於 0-1  的數字，不包含 1。

  ```javascript
  alert( Math.random() ); // 0.1234567894322
  alert( Math.random() ); // 0.5435252343232
  alert( Math.random() ); // ... (any random numbers)
  ```
* &#x20;`Math.max(a, b, c...)` / `Math.min(a, b, c...)` 返回最大 / 最小的數字。

  ```javascript
  alert( Math.max(3, 5, -10, 0, 1) ); // 5
  alert( Math.min(1, 2) ); // 1
  ```
* `Math.pow(n, power)` 返回數字的次方

  ```javascript
  alert( Math.pow(2, 10) ); // 2 in power 10 = 1024
  ```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mistborn.gitbook.io/til-coding/javascript/numbers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
