---
type: reference
language: javascript
slug: number/rounding
title: "数値を丸める — Math.round / floor / ceil / trunc と toFixed"
title_tag: "JavaScript の丸め — round と toFixed の違いと落とし穴"
summary: >
  4つの丸め方の違い、負の数で結果が分かれる理由、toFixed が文字列を返すこと、
  そして 1.005 が 1.00 になる理由と、その回避策も効かない場面までを実行して確かめます。
description: >
  Math.round(-2.5) は -2 です。四捨五入ではありません。toFixed(2) が 1.005 を 1.00 に
  する理由、桁を掛けて丸める回避策も効かない場面まで実行して確かめられます。
status: published
difficulty: 2
minutes: 9

versions:
  verified: "Node 22.22.3"
  since: "ES1"
  deprecated: null
  removed: null

sources:
  - title: "Math.round — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-math.round"
  - title: "Number.prototype.toFixed — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-number.prototype.tofixed"
  - title: "IEEE 754-2019 — IEEE Standard for Floating-Point Arithmetic"
    url: "https://standards.ieee.org/ieee/754/6210/"

terms: [丸め, 切り捨て, 浮動小数点数, 有効桁]

links:
  related:
    - javascript/why/float-precision
    - javascript/how-to/string/to-number
    - javascript/how-to/array/sum

content_updated_at: 2026-09-08
published_at: 2026-09-08
---

丸め方は[num:4]つあります。**負の数で結果が分かれます。**

```js run
for (const n of [2.5, -2.5, 2.4, -2.4]) {
  console.log(String(n).padStart(5), Math.round(n), Math.floor(n), Math.ceil(n), Math.trunc(n));
}
```
```output
  2.5 3 2 3 2
 -2.5 -2 -3 -2 -2
  2.4 2 2 3 2
 -2.4 -2 -3 -2 -2
```

| 関数 | やること | `-2.5` |
|---|---|---|
| `Math.round()` | **より大きいほうへ**（`+0.5` して切り捨て） | `-2` |
| `Math.floor()` | 小さいほうへ（下へ） | `-3` |
| `Math.ceil()` | 大きいほうへ（上へ） | `-2` |
| `Math.trunc()` | [num:0]へ（小数を捨てる） | `-2` |

## `Math.round()` は四捨五入ではない

**`-2.5` が `-2` になります。** 四捨五入なら `-3` のはずです。

`Math.round()` は「[key:0.5 を足して切り捨てる]」という決まりです。
正の数では四捨五入と同じ結果になりますが、**負の数ではずれます。**

「絶対値で四捨五入」したいなら、自分で書きます。

```js run
function roundHalfAwayFromZero(n) {
  return Math.sign(n) * Math.round(Math.abs(n));
}

console.log(Math.round(-2.5), roundHalfAwayFromZero(-2.5));
console.log(Math.round(2.5), roundHalfAwayFromZero(2.5));
```
```output
-2 -3
3 3
```

**「四捨五入」と言われたら、負の数をどうするか先に確かめてください。**

## `toFixed()` は文字列を返す

```js run
console.log((1234.5678).toFixed(2));
console.log(typeof (1234.5678).toFixed(2));
```
```output
1234.57
string
```

**数値ではありません。** そのまま足すと文字列の連結になります。

```js bad
console.log((1.5).toFixed(1) + 1);
```
```output
1.51
```

計算に戻すなら `Number()` を通してください。
→ [文字列を数値に変換する](/ja/javascript/how-to/string/to-number/)

## `1.005` が `1.00` になる

**いちばん有名な落とし穴です。**

```js run
console.log((1.005).toFixed(2));
console.log((1.015).toFixed(2));
console.log((1.025).toFixed(2));
```
```output
1.00
1.01
1.02
```

3つとも[bad:切り上がっていません]。

理由は `toFixed()` の不具合ではありません。**`1.005` という数がそもそも存在しない**からです。
二進法で書けないので、実際には `1.005` よりわずかに小さい数が入っています。
→ [なぜ 0.1 + 0.2 は 0.30000000000000004 になるのか](/ja/javascript/why/float-precision/)

### よくある回避策も効かない

「100倍して丸めて戻す」という書き方が知られています。**これも同じ理由で外れます。**

```js run
function roundTo(n, digits) {
  const p = 10 ** digits;
  return Math.round(n * p) / p;
}

console.log(roundTo(1.005, 2));
console.log(1.005 * 100);
```
```output
1
100.49999999999999
```

`1.005 * 100` が `100.49999999999999` なので、`Math.round()` は `100` にします。
**掛けた時点でずれています。**

[dim:`roundTo(1.234567, 3)` のような普通の値では正しく働きます。効かないのは、二進法で表せない値がちょうど境界に来たときです。]

### どうすればよいか

**お金や数量のように「ずれてはいけない数」は、小数で持たないでください。**

```js run
const yen = 1005;

console.log(yen / 100);
console.log((yen / 100).toFixed(2));
console.log(Math.round(yen / 10) * 10);
```
```output
10.05
10.05
1010
```

[em:最小単位（円・グラム・ミリ秒）の整数で持ち、表示するときだけ割る。]
これがいちばん確実です。

**表示だけが目的なら `toFixed()` で十分**です。1円のずれが問題になる計算に使わない、
というだけの話です。

## 桁区切りや通貨は `Intl` に任せる

```js run
console.log((1234567.891).toLocaleString('ja-JP'));
console.log((1234567.891).toLocaleString('ja-JP', { maximumFractionDigits: 0 }));
console.log((1234.5).toLocaleString('ja-JP', { style: 'currency', currency: 'JPY' }));
```
```output
1,234,567.891
1,234,568
￥1,235
```

**自分で3桁ごとにカンマを入れないでください。**
言語ごとの区切り方は `Intl` が知っています。

[dim:ロケールを省くと環境の設定で結果が変わります。必ず `'ja-JP'` のように書いてください。]

## 整数かどうかを確かめる

```js run
console.log(Number.isInteger(3), Number.isInteger(3.0), Number.isInteger(3.5));
console.log(Number.MAX_SAFE_INTEGER);
console.log(Number.isSafeInteger(2 ** 53 - 1), Number.isSafeInteger(2 ** 53));
```
```output
true true false
9007199254740991
true false
```

`3.0` は `3` と同じ数です。JavaScript に[bad:整数型と小数型の区別はありません]。

**安全に扱える整数は `2^53 - 1` まで**です。それを超えると、隣の数と区別できなくなります。

```js run
console.log(2 ** 53 === 2 ** 53 + 1);
```
```output
true
```

大きな識別子は `BigInt` か文字列で持ってください。

## まとめ

- **`Math.round()` は四捨五入ではない。** `-2.5` は `-2`
- [num:0]へ寄せるなら `Math.trunc()`、下へなら `floor()`、上へなら `ceil()`
- `toFixed()` は[key:文字列]を返す。足すと連結になる
- **`(1.005).toFixed(2)` は `1.00`。** その数がそもそも無いから
- 100倍して丸める回避策も、同じ理由で外れることがある
- **ずれてはいけない数は、最小単位の整数で持つ**
- 桁区切りと通貨は `toLocaleString()`。ロケールを必ず書く
