Skip to content

Commit 6fea53e

Browse files
committed
Refactor number formatting and rounding in article.md
1 parent 7f435c2 commit 6fea53e

File tree

1 file changed

+162
-1
lines changed

1 file changed

+162
-1
lines changed

1-js/05-data-types/02-number/article.md

Lines changed: 162 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,4 +280,165 @@ alert( 9999999999999999 ); // แสดง 10000000000000000
280280
JavaScript ไม่ทำให้เกิดข้อผิดพลาดในเหตุการณ์เช่นนี้ มันพยายามอย่างดีที่สุดเพื่อให้ตัวเลขพอดีกับรูปแบบที่ต้องการ แต่น่าเสียดายที่รูปแบบนี้ไม่ใหญ่พอ
281281
````
282282

283-
```smart header="ศูนย์สองตัว"
283+
```smart header="ศูนย์สองตัว"
284+
ผลที่ตลกอีกอย่างหนึ่งของการแสดงตัวเลขภายในคือการมีศูนย์สองตัว: `0` และ `-0`
285+
286+
นั่นเป็นเพราะเครื่องหมายถูกแสดงด้วยบิตเดียว ดังนั้นจึงสามารถตั้งค่าหรือไม่ตั้งค่าสำหรับตัวเลขใดๆ รวมถึงศูนย์
287+
288+
ในกรณีส่วนใหญ่ ความแตกต่างไม่สามารถสังเกตเห็นได้ เพราะตัวดำเนินการถูกปรับให้ปฏิบัติต่อพวกมันเหมือนกัน
289+
```
290+
291+
## การทดสอบ: isFinite และ isNaN
292+
293+
จำค่าตัวเลขพิเศษสองตัวนี้ได้ไหม?
294+
295+
- `Infinity` (และ `-Infinity`) เป็นค่าตัวเลขพิเศษที่มากกว่า (น้อยกว่า) ทุกอย่าง
296+
- `NaN` แสดงถึงข้อผิดพลาด
297+
298+
พวกมันเป็นของประเภท `number` แต่ไม่ใช่ตัวเลข "ปกติ" ดังนั้นจึงมีฟังก์ชันพิเศษเพื่อตรวจสอบพวกมัน:
299+
300+
301+
- `isNaN(value)` แปลงอาร์กิวเมนต์ของมันเป็นตัวเลขและจากนั้นทดสอบว่าเป็น `NaN`:
302+
303+
```js run
304+
alert( isNaN(NaN) ); // จริง
305+
alert( isNaN("str") ); // จริง
306+
```
307+
308+
แต่เราจำเป็นต้องใช้ฟังก์ชันนี้หรือไม่? เราไม่สามารถใช้การเปรียบเทียบ `=== NaN` ได้หรือ? ขอโทษ แต่คำตอบคือไม่ได้ ค่า `NaN` เป็นเอกลักษณ์ในการที่มันไม่เท่ากับอะไรเลย รวมถึงตัวมันเอง:
309+
310+
```js run
311+
alert( NaN === NaN ); // เท็จ
312+
```
313+
314+
- `isFinite(value)` แปลงอาร์กิวเมนต์ของมันเป็นตัวเลขและคืนค่า `จริง` ถ้ามันเป็นตัวเลขปกติ ไม่ใช่ `NaN/Infinity/-Infinity`:
315+
316+
```js run
317+
alert( isFinite("15") ); // จริง
318+
alert( isFinite("str") ); // เท็จ เพราะเป็นค่าพิเศษ: NaN
319+
alert( isFinite(Infinity) ); // เท็จ เพราะเป็นค่าพิเศษ: Infinity
320+
```
321+
322+
บางครั้ง `isFinite` ถูกใช้เพื่อตรวจสอบว่าค่าสตริงเป็นตัวเลขปกติหรือไม่:
323+
324+
325+
```js run
326+
let num = +prompt("ป้อนตัวเลข", '');
327+
328+
// จะเป็นจริงยกเว้นคุณป้อน Infinity, -Infinity หรือไม่ใช่ตัวเลข
329+
alert( isFinite(num) );
330+
```
331+
332+
โปรดทราบว่าสตริงว่างเปล่าหรือสตริงที่มีเฉพาะช่องว่างจะถูกปฏิบัติเป็น `0` ในทุกฟังก์ชันตัวเลขรวมถึง `isFinite`
333+
334+
```smart header="เปรียบเทียบกับ `Object.is`"
335+
336+
มีวิธีการในตัวพิเศษ [`Object.is`](mdn:js/Object/is) ที่เปรียบเทียบค่าเหมือน `===` แต่น่าเชื่อถือมากกว่าสำหรับสองกรณีพิเศษ:
337+
338+
1. มันทำงานกับ `NaN`: `Object.is(NaN, NaN) === true` นั่นเป็นสิ่งที่ดี
339+
2. ค่า `0` และ `-0` แตกต่างกัน: `Object.is(0, -0) === false` ทางเทคนิคแล้วนั่นเป็นความจริง เพราะภายในตัวเลขมีบิตเครื่องหมายที่อาจแตกต่างกันแม้ว่าบิตอื่นๆ ทั้งหมดจะเป็นศูนย์
340+
341+
ในทุกกรณีอื่นๆ `Object.is(a, b)` เหมือนกับ `a === b`
342+
343+
วิธีการเปรียบเทียบนี้มักใช้ในข้อกำหนดของ JavaScript เมื่ออัลกอริทึมภายในต้องการเปรียบเทียบสองค่าว่าเหมือนกันพอดีหรือไม่ มันใช้ `Object.is` (เรียกภายในว่า [SameValue](https://tc39.github.io/ecma262/#sec-samevalue))
344+
```
345+
346+
347+
## parseInt และ parseFloat
348+
349+
การแปลงเป็นตัวเลขโดยใช้เครื่องหมายบวก `+` หรือ `Number()` นั้นเข้มงวด ถ้าค่าไม่ใช่ตัวเลขพอดี มันจะล้มเหลว:
350+
351+
```js run
352+
alert( +"100px" ); // NaN
353+
```
354+
355+
ข้อยกเว้นเพียงอย่างเดียวคือช่องว่างที่อยู่ต้นหรือท้ายสตริง เพราะมันจะถูกละเลย
356+
357+
แต่ในชีวิตจริง เรามักจะมีค่าในหน่วยต่างๆ เช่น `"100px"` หรือ `"12pt"` ใน CSS และในหลายประเทศสัญลักษณ์สกุลเงินจะอยู่หลังจำนวนเงิน ดังนั้นเราจึงมี `"19€"` และต้องการแยกค่าตัวเลขออกมา
358+
359+
นั่นคือสิ่งที่ `parseInt` และ `parseFloat` มีไว้
360+
361+
พวกมัน "อ่าน" ตัวเลขจากสตริงจนกว่าจะไม่สามารถอ่านได้ ในกรณีที่เกิดข้อผิดพลาด ตัวเลขที่รวบรวมได้จะถูกส่งคืน ฟังก์ชัน `parseInt` ส่งคืนจำนวนเต็ม ในขณะที่ `parseFloat` จะส่งคืนตัวเลขที่มีทศนิยม:
362+
363+
```js run
364+
alert( parseInt('100px') ); // 100
365+
alert( parseFloat('12.5em') ); // 12.5
366+
367+
alert( parseInt('12.3') ); // 12, เฉพาะส่วนจำนวนเต็มถูกส่งคืน
368+
alert( parseFloat('12.3.4') ); // 12.3, จุดที่สองหยุดการอ่าน
369+
```
370+
371+
มีสถานการณ์ที่ `parseInt/parseFloat` จะส่งคืน `NaN` มันเกิดขึ้นเมื่อไม่สามารถอ่านตัวเลขได้เลย:
372+
373+
```js run
374+
alert( parseInt('a123') ); // NaN, สัญลักษณ์แรกหยุดกระบวนการ
375+
```
376+
377+
````smart header="อาร์กิวเมนต์ที่สองของ `parseInt(str, radix)`"
378+
ฟังก์ชัน `parseInt()` มีพารามิเตอร์ที่สองซึ่งเป็นตัวเลือก มันระบุฐานของระบบตัวเลข ดังนั้น `parseInt` สามารถแยกวิเคราะห์สตริงของตัวเลขฐานสิบหก ตัวเลขฐานสอง และอื่นๆ ได้:
379+
380+
```js run
381+
alert( parseInt('0xff', 16) ); // 255
382+
alert( parseInt('ff', 16) ); // 255, ไม่มี 0x ก็ทำงานได้
383+
384+
alert( parseInt('2n9c', 36) ); // 123456
385+
```
386+
````
387+
388+
## ฟังก์ชันทางคณิตศาสตร์อื่นๆ
389+
390+
JavaScript มีวัตถุ [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) ในตัวซึ่งมีไลบรารีขนาดเล็กของฟังก์ชันทางคณิตศาสตร์และค่าคงที่
391+
392+
ตัวอย่างบางส่วน:
393+
394+
`Math.random()`
395+
: ส่งคืนตัวเลขสุ่มตั้งแต่ 0 ถึง 1 (ไม่รวม 1)
396+
397+
```js run
398+
alert( Math.random() ); // 0.1234567894322
399+
alert( Math.random() ); // 0.5435252343232
400+
alert( Math.random() ); // ... (ตัวเลขสุ่มใดๆ)
401+
```
402+
403+
`Math.max(a, b, c...)` / `Math.min(a, b, c...)`
404+
: ส่งคืนค่าที่มากที่สุด/น้อยที่สุดจากอาร์กิวเมนต์จำนวนใดๆ
405+
406+
```js run
407+
alert( Math.max(3, 5, -10, 0, 1) ); // 5
408+
alert( Math.min(1, 2) ); // 1
409+
```
410+
411+
`Math.pow(n, power)`
412+
: ส่งคืน `n` ยกกำลัง `power`
413+
414+
```js run
415+
alert( Math.pow(2, 10) ); // 2 ยกกำลัง 10 = 1024
416+
```
417+
418+
มีฟังก์ชันและค่าคงที่อื่นๆ อีกมากใน `Math` รวมถึงตรีโกณมิติ ซึ่งคุณสามารถพบได้ในเอกสารสำหรับวัตถุ [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math)
419+
420+
## สรุป
421+
422+
การเขียนตัวเลขที่มีศูนย์จำนวนมาก:
423+
424+
- ต่อท้าย `"e"` กับจำนวนศูนย์ไปยังตัวเลข เช่น: `123e6` เหมือนกับ `123` ตามด้วยศูนย์ 6 ตัว `123000000`
425+
- ตัวเลขลบหลัง `"e"` ทำให้ตัวเลขถูกหารด้วย 1 ตามด้วยจำนวนศูนย์ที่กำหนด เช่น `123e-6` หมายถึง `0.000123` (`123` หนึ่งในล้าน)
426+
427+
สำหรับระบบตัวเลขต่างๆ:
428+
429+
- สามารถเขียนตัวเลขโดยตรงในระบบฐานสิบหก (`0x`), ฐานแปด (`0o`) และฐานสอง (`0b`)
430+
- `parseInt(str, base)` แยกวิเคราะห์สตริง `str` เป็นจำนวนเต็มในระบบตัวเลขที่มีฐาน `base`, `2 ≤ base ≤ 36`
431+
- `num.toString(base)` แปลงตัวเลขเป็นสตริงในระบบตัวเลขที่มีฐานที่กำหนด
432+
433+
สำหรับการแปลงค่าเช่น `12pt` และ `100px` เป็นตัวเลข:
434+
435+
- ใช้ `parseInt/parseFloat` สำหรับการแปลง "แบบนุ่มนวล" ซึ่งอ่านตัวเลขจากสตริงและจากนั้นส่งคืนค่าที่สามารถอ่านได้ก่อนเกิดข้อผิดพลาด
436+
437+
สำหรับเศษส่วน:
438+
439+
- ปัดเศษโดยใช้ `Math.floor`, `Math.ceil`, `Math.trunc`, `Math.round` หรือ `num.toFixed(precision)`
440+
- ต้องแน่ใจว่าจำไว้ว่ามีการสูญเสียความแม่นยำเมื่อทำงานกับเศษส่วน
441+
442+
ฟังก์ชันทางคณิตศาสตร์เพิ่มเติม:
443+
444+
- ดูวัตถุ [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) เมื่อคุณต้องการใช้ ไลบรารีนี้มีขนาดเล็กมาก แต่สามารถครอบคลุมความต้องการทางคณิตศาสตร์ที่สำคัญ

0 commit comments

Comments
 (0)