JavaScript: JavaScript 数字与数学
在 JavaScript 里,数字只有一个类型——Number。不管你是整数还是小数,统统都是 Number。这跟 Java、C 那些分 int、float 的语言不一样,简单是简单了,但也埋着几个坑。
1. 数字类型
JavaScript 中整数和浮点数都是 Number 类型,没有独立的整数类型。
HTML
<script>
let a = 42; // 这是个 Number
let b = 3.14; // 这也是 Number
typeof a; // "number"
typeof b; // "number"
</script>
数字的表示方式还有几种:
HTML
<script>
let hex = 0xFF; // 十六进制,等于 255
let octal = 0o10; // 八进制,等于 8
let binary = 0b1010; // 二进制,等于 10
let big = 1e6; // 科学计数法,等于 1000000
</script>
▶ 示例
JAVASCRIPT
// 本节代码示例
const message = "你好,世界!";
console.log(message);
这是最简单的示例,后续章节会详细解释。## 2. NaN 和 Infinity
NaN 的全称是 Not a Number,但它偏偏是 Number 类型——这是 JavaScript 最讽刺的设计之一。
HTML
<script>
typeof NaN; // "number" ← 没错,它竟然是 number 类型
NaN === NaN; // false ← 自己不等于自己!
Number.isNaN(NaN); // true ← 这才对,用这个方法检测
</script>
什么时候会出现 NaN?把字符串当数字运算时:
HTML
<script>
parseInt('abc'); // NaN
'hello' * 5; // NaN
Math.sqrt(-1); // NaN
</script>
Infinity 表示无穷大,除以 0 时会出现:
HTML
<script>
1 / 0; // Infinity
-1 / 0; // -Infinity
typeof Infinity; // "number"
</script>
💡 提示: 判断一个值是不是 NaN,千万别用
===,用 Number.isNaN()。因为 NaN === NaN 是 false,这坑无数人踩过。
3. 数值精度问题
这是 JavaScript 最著名的"冷知识":0.1 + 0.2 !== 0.3。
HTML
<script>
0.1 + 0.2; // 0.30000000000000004
0.1 + 0.2 === 0.3; // false
</script>
原因跟计算机用二进制存储浮点数有关,0.1 在二进制里是无限循环小数,存储时有精度丢失。不光 JavaScript,所有用 IEEE 754 标准的语言都有这个问题。
解决办法:用 toFixed() 格式化,或者乘以大数再运算:
HTML
<script>
(0.1 + 0.2).toFixed(2); // "0.30"
(0.1 * 100 + 0.2 * 100) / 100; // 0.3
</script>
▶ 示例:精度问题演示
HTML
<!DOCTYPE html>
<html>
<body>
<h2>浮点数精度问题</h2>
<p id="output"></p>
<script>
let html = '';
html += '0.1 + 0.2 = ' + (0.1 + 0.2) + '<br>';
html += '0.1 + 0.2 === 0.3 ? ' + (0.1 + 0.2 === 0.3) + '<br><br>';
html += '<strong>解决方案1:toFixed</strong><br>';
html += '(0.1 + 0.2).toFixed(2) = ' + (0.1 + 0.2).toFixed(2) + '<br><br>';
html += '<strong>解决方案2:放大再缩小</strong><br>';
html += '(0.1*100 + 0.2*100)/100 = ' + ((0.1 * 100 + 0.2 * 100) / 100) + '<br><br>';
html += '<strong>NaN 相关:</strong><br>';
html += 'parseInt("abc") = ' + parseInt('abc') + '<br>';
html += 'NaN === NaN ? ' + (NaN === NaN) + '<br>';
html += 'Number.isNaN(NaN) ? ' + Number.isNaN(NaN) + '<br><br>';
html += '<strong>Infinity 相关:</strong><br>';
html += '1 / 0 = ' + (1 / 0) + '<br>';
html += 'typeof Infinity = ' + typeof Infinity;
document.getElementById('output').innerHTML = html;
</script>
</body>
</html>
4. Math 对象
Math 是 JavaScript 内置的数学工具箱,不用创建实例,直接调用方法:
| 方法/属性 | 作用 | 示例 |
|---|---|---|
Math.round() |
四舍五入 | Math.round(4.6) → 5 |
Math.floor() |
向下取整 | Math.floor(4.9) → 4 |
Math.ceil() |
向上取整 | Math.ceil(4.1) → 5 |
Math.random() |
0~1 随机数 | Math.random() → 0.3721... |
Math.max() |
最大值 | Math.max(1,5,3) → 5 |
Math.min() |
最小值 | Math.min(1,5,3) → 1 |
Math.PI |
圆周率 | 3.141592653589793 |
Math.abs() |
绝对值 | Math.abs(-7) → 7 |
Math.pow() |
幂运算 | Math.pow(2,3) → 8 |
Math.sqrt() |
平方根 | Math.sqrt(16) → 4 |
▶ 示例:Math 常用方法
HTML
<!DOCTYPE html>
<html>
<body>
<h2>Math 对象方法</h2>
<p id="output"></p>
<script>
let html = '';
html += 'Math.round(4.6) = ' + Math.round(4.6) + '<br>';
html += 'Math.round(4.4) = ' + Math.round(4.4) + '<br>';
html += 'Math.floor(4.9) = ' + Math.floor(4.9) + '<br>';
html += 'Math.ceil(4.1) = ' + Math.ceil(4.1) + '<br>';
html += 'Math.abs(-7) = ' + Math.abs(-7) + '<br>';
html += 'Math.pow(2, 10) = ' + Math.pow(2, 10) + '<br>';
html += 'Math.sqrt(144) = ' + Math.sqrt(144) + '<br>';
html += 'Math.max(1, 5, 3) = ' + Math.max(1, 5, 3) + '<br>';
html += 'Math.min(1, 5, 3) = ' + Math.min(1, 5, 3) + '<br>';
html += 'Math.PI = ' + Math.PI + '<br>';
let radius = 5;
let area = Math.PI * Math.pow(radius, 2);
html += `半径为 ${radius} 的圆面积 = ${area.toFixed(2)}`;
document.getElementById('output').innerHTML = html;
</script>
</body>
</html>
💡 提示:
Math.round(-1.5) 的结果是 -1,不是 -2。四舍五入在负数边界上的行为可能跟你直觉不一样,需要留意。
5. toFixed() 格式化小数
toFixed(n) 把数字格式化为 n 位小数的字符串:
HTML
<script>
let price = 9.9;
price.toFixed(2); // "9.90" ← 注意返回的是字符串
+(9.9).toFixed(2); // 9.9 ← 用 + 转回数字
</script>
⚠️ 注意:
toFixed 返回的是字符串!如果后续还要做运算,记得转回数字。
6. toString() 进制转换
数字的 toString(radix) 可以把数字转成指定进制的字符串:
HTML
<script>
(255).toString(16); // "ff" 十六进制
(255).toString(2); // "11111111" 二进制
(255).toString(8); // "377" 八进制
(100).toString(); // "100" 默认十进制
</script>
▶ 示例:进制转换
HTML
<!DOCTYPE html>
<html>
<body>
<h2>进制转换</h2>
<p id="output"></p>
<script>
let num = 255;
let html = `数字 ${num} 的各进制表示:<br><br>`;
html += `十进制:${num.toString()}<br>`;
html += `二进制:${num.toString(2)}<br>`;
html += `八进制:${num.toString(8)}<br>`;
html += `十六进制:${num.toString(16)}<br><br>`;
let price = 19.9;
html += `价格格式化:¥${price.toFixed(2)}<br>`;
html += `toFixed 返回类型:${typeof price.toFixed(2)}<br>`;
document.getElementById('output').innerHTML = html;
</script>
</body>
</html>
7. Math.random() 生成随机数
Math.random() 返回 0 到 1 之间的随机浮点数(包含 0,不包含 1)。实际使用时,我们经常需要生成某个范围内的随机整数:
HTML
<script>
// 生成 min 到 max 之间的随机整数(包含 min 和 max)
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
</script>
▶ 示例:随机数演示
HTML
<!DOCTYPE html>
<html>
<body>
<h2>随机数生成器</h2>
<button onclick="rollDice()">掷骰子</button>
<button onclick="pickLotto()">随机选号(1-35)</button>
<p id="output"></p>
<script>
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function rollDice() {
let dice = getRandomInt(1, 6);
let dots = '';
for (let i = 0; i < dice; i++) {
dots += ' ⚀';
}
document.getElementById('output').innerHTML =
`你掷出了 <strong>${dice}</strong> 点${dots}`;
}
function pickLotto() {
let numbers = [];
while (numbers.length < 5) {
let n = getRandomInt(1, 35);
if (!numbers.includes(n)) {
numbers.push(n);
}
}
numbers.sort((a, b) => a - b);
document.getElementById('output').innerHTML =
`你的幸运号码:<strong>${numbers.join(' ')}</strong>`;
}
</script>
</body>
</html>
💡 提示:
Math.random() 是伪随机数,不适合加密场景。需要加密安全的随机数,用 crypto.getRandomValues()。
❓ 常见问题
Q
Math.round(2.5) 和 Math.round(-2.5) 分别是多少?A
Math.round(2.5) 是 3,Math.round(-2.5) 是 -2。当恰好是 .5 时,JavaScript 向正无穷方向舍入,所以正数往上靠、负数也往上靠(更接近 0)。Q 怎么判断一个值是不是合法的有限数字?
A 用
Number.isFinite(value),它能排除 NaN、Infinity 和 -Infinity,也排除非数字类型。isFinite() 也行但不检查类型(会先转换)。Q
parseInt 和 Number() 有什么区别?A
parseInt('12abc') 返回 12,它从左到右解析到不能解析为止;Number('12abc') 返回 NaN,整个字符串必须是合法数字。需要宽松解析用 parseInt,严格转换用 Number()。📖 小节
- JavaScript 只有
Number一种数字类型,整数和小数都是 Number NaN不等于任何值(包括自己),检测用Number.isNaN()0.1 + 0.2 !== 0.3是精度问题,用toFixed()或放大再缩小解决Math.floor向下取整,Math.ceil向上取整,Math.round四舍五入- 生成随机整数公式:
Math.floor(Math.random() * (max - min + 1)) + min toFixed()返回字符串,后续要运算记得转回数字
📝 作业
- 写一个程序,让用户输入圆的半径,计算圆的面积和周长,结果保留 2 位小数
- 写一个猜数字游戏:程序随机生成 1-100 的整数,用户输入猜测,提示"大了"或"小了",直到猜对
- 写一个进制转换器:输入一个十进制数,同时显示其二进制、八进制、十六进制结果