59 điểm bởi GN⁺ 2025-02-17 | 12 bình luận | Chia sẻ qua WhatsApp

"Ứng dụng máy tính à? Ai mà chẳng làm được" → thực ra không đúng

  • Máy tính phải hiển thị chính xác kết quả của các biểu thức toán học, và việc này khó hơn nhiều so với tưởng tượng
  • Trên máy tính của iOS, (10^100) + 1 − (10^100) bị tính sai thành 0
  • Nhưng Android lại cho ra kết quả đúng là 1, và cách họ làm điều đó thực sự khó tin

Google và Hans-J. Boehm

  • Google đã tuyển dụng lập trình viên nổi tiếng Hans-J. Boehm
  • Boehm là chuyên gia đã định nghĩa ngữ nghĩa của biến dùng chung trong C++
  • Nhưng nhiệm vụ được giao cho ông lại là phát triển ứng dụng máy tính, một việc ngoài dự đoán

Vấn đề của số dấu phẩy động

  • Số dấu phẩy động không thể biểu diễn chính xác các giá trị như 0.3 hay 10^100
  • Nghĩa là máy tính dựa trên số dấu phẩy động không thể đáng tin cậy
  • Để tính toán chính xác, cần một cách tiếp cận khác

Giải pháp dùng Bignum

  • Bài toán tính số nguyên có thể được giải bằng Bignum (số nguyên không giới hạn)
  • Bignum là kiểu số nguyên có thể mở rộng động theo dung lượng bộ nhớ
  • Bài toán (10^100) + 1 - (10^100) có thể được giải bằng Bignum
  • Nhưng phép toán với phân số vẫn chưa được giải quyết
Quảng cáo

Phân số và số đại số

  • Phân số (như giá trị 3/4) có thể được xử lý bằng cách dùng Bignum để lưu tử số và mẫu số
  • Nhưng không thể biểu diễn các số vô tỉ như số pi (π) hay căn bậc hai của 2 (√2)
  • Boehm đã thử cách biểu diễn dựa trên đa thức
    • Ví dụ: √2 có thể được biểu diễn bằng phương trình x² - 2 = 0
    • Nhưng π thì ngay cả cách này cũng không thể biểu diễn được

Số thực kiến tạo (Constructive Real Numbers)

  • Boehm đã nghiên cứu khái niệm "phép toán số thực đệ quy (RRA)"
  • Khi người dùng nhập độ chính xác mong muốn, hệ thống sẽ tính giá trị trong phạm vi độ chính xác đó
  • Ví dụ: nếu biểu diễn π trong sai số 0.01 thì sẽ trả về 3.14
  • Nhưng cách này khiến việc so sánh chính xác trở nên khó khăn

Vấn đề biểu diễn số 0 chính xác

  • Theo cách RRA, 1 - 1 có thể được biểu diễn không phải là 0 mà là 0.0000000001
  • Điều này gây vấn đề về mặt trải nghiệm người dùng (UX)
  • Boehm bắt đầu hợp tác với các nhà nghiên cứu khác để tìm lời giải

Thuật toán Richardson-Fitch

  • Năm 1994, Dan Richardson và John Fitch đã giải quyết bài toán so sánh số trong một số phép toán nhất định
  • Nhưng thuật toán này quá chậm nên trên thực tế không thể dùng được
  • Ví dụ, để xác định 1 ≠ 1 - e^(-e^1000) cần số phép tính còn nhiều hơn cả số nguyên tử trong vũ trụ
Quảng cáo

Kết hợp RRA và phép toán hữu tỉ

  • Boehm nảy ra ý tưởng kết hợp ưu điểm của RRA với phép toán trên số hữu tỉ
  • Với các phép toán đơn giản (ví dụ: 6 × 9 hoặc 8 / 3) thì dùng phép toán hữu tỉ
  • Chỉ khi có số vô tỉ mới dùng RRA
  • Kết quả là biểu diễn số dưới dạng hữu tỉ × số thực

Biểu diễn ký hiệu (Symbolic Representation)

  • Các số đặc biệt như π, √2 được dùng biểu diễn ký hiệu thay vì RRA
  • Ví dụ: π được lưu dưới dạng ký hiệu "π" và chỉ chuyển thành số khi cần
  • Không chỉ bốn phép toán cơ bản, mà cả các hàm lượng giác (sin, cos, tan), log và hàm mũ cũng tận dụng biểu diễn ký hiệu

Giải pháp cuối cùng

  • Mọi số đều được lưu dưới dạng hữu tỉ × số thực (biểu diễn ký hiệu hoặc RRA)
  • Khi có thể thì dùng phép toán hữu tỉ để giữ độ chính xác
  • Tận dụng biểu diễn ký hiệu tối đa để giảm thiểu phép toán RRA
  • Kết quả là hoàn thiện được một hệ thống máy tính lý tưởng, cân bằng giữa tốc độ và độ chính xác

Kết luận

  • Ứng dụng máy tính Android do Boehm và nhóm của ông tạo ra không phải là một chương trình đơn giản
  • Nó áp dụng các thuật toán nhanh và hiệu quả mà vẫn cho kết quả chính xác
  • Đây không phải "chỉ là một ứng dụng máy tính", mà là một hệ thống tinh vi về mặt toán học

"Lần tới khi dùng máy tính Android, hãy nhớ đến nỗ lực này!"

12 bình luận

 
street62 2025-02-20

Ngoài lề một chút, khá thú vị là AI neo đã dịch thành “thế chứ”. Nguyên văn là “Anyone could make that” nên không có sắc thái đùa cợt như vậy đâu haha, nhưng lại hợp cực kỳ.

 
gurugio 2025-02-19

Hồi còn là sinh viên đại học, tôi từng có một môn học mà phải tự tay hàn một bo mạch 8086, nối bàn phím số và LCD chữ vào, rồi dùng hợp ngữ 8086 để làm cả một chiếc máy tính bỏ túi chỉ thực hiện bốn phép tính cơ bản.
Tôi đã làm bo mạch, nối cả bàn phím lẫn LCD và cho nó chạy được, nhưng lại không làm được máy tính.
Lúc đó tôi nghĩ mình không có năng khiếu về phần mềm nên đã đi làm kỹ sư phần cứng, nhưng rồi chẳng hiểu sao bây giờ lại đang phát triển phần mềm.
Máy tính thật sự rất khó.

 
yunsub2 2025-02-19

Phải là “geojanh-a” chứ không phải “geojana”. 😃

 
carnoxen 2025-02-18

Muốn xử lý điều chỉnh số dấu phẩy động thì cũng đau đầu lắm đấy? hahaha

 
tribela 2025-02-18

Nhắc đến ứng dụng máy tính, tôi lại nghĩ ngay tới máy tính mặc định của Windows. Nếu tính 2+2*2 thì nó cho ra 8 chứ không phải 6. Có vẻ như họ cố tình làm vậy, nhưng tôi hoàn toàn không hiểu nổi. Trước đây tôi từng tính lượng cồn trong một ly cocktail, kết quả cho ra lượng cồn còn nhiều hơn cả tổng lượng đồ uống nên đã có một phen bối rối.

 
khrad 2025-02-19

Đây là kiểu hoạt động của máy tính điện tử thông thường, mỗi lần bấm toán tử thì biểu thức trước đó sẽ được tính ngay; chẳng lẽ bạn chỉ mới dùng máy tính khoa học thôi sao?

 
ned0909 2025-02-18

Hoàn toàn đồng cảm. Lúc đầu tôi chọn làm ứng dụng máy tính vì thấy không cần máy chủ nên sẽ ổn, ai ngờ sau đó phải vật lộn rất vất vả để bắt các lỗi tính toán và bug phát sinh.

 
aer0700 2025-02-17

"Ứng dụng máy tính à? Ai mà chả làm được" → thực ra không phải vậy
Có vẻ cái này có thể ứng dụng vào vô số chỗ luôn ấy chứ haha

"Python á? Dễ ẹc mà" → thực ra không phải vậy

 
tsboard 2025-02-17

Tôi cũng đã nghĩ y như vậy khi xem. haha

"JavaScript á? Dễ như ăn kẹo ấy mà" → thật ra không phải vậy

 
joyfui 2025-02-17

"(10^100)+1−(10^100)"
Ồ, thật sự máy tính trên iPhone hiển thị 0, còn máy tính trên Android hiển thị 1.
Nhưng khi tìm kiếm trên Google thì lại hiện ra 0...

 
GN⁺ 2025-02-17
Bình luận trên Hacker News
  • Câu chuyện khá thú vị. Một cách mạnh hơn để biểu diễn số là dùng phân số liên tục. Phân số liên tục có thể biểu diễn hiệu quả số thực và số hữu tỉ
    • Một điều thú vị là, theo các giáo trình toán không quá cũ, rất có thể không tồn tại thuật toán cộng/nhân cho phân số liên tục. Tuy nhiên, năm 1972 Bill Gosper đã chứng minh rằng phân số liên tục hoàn toàn phù hợp cho số học
    • Tôi đang phát triển một thư viện Python tên là reals. Thư viện này được thiết kế để thay thế các kiểu Decimal hoặc Fraction. Nó thao tác phân số liên tục bằng kỹ thuật của Bill Gosper
  • Thật đáng tiếc khi liên kết bị rút ngắn nên không thể nhấp vào. Đây là liên kết thực tới bài báo
  • Tôi đã bật cười ngay khi đọc tiêu đề. IEEE 754 thì tệ nhất, nhưng vẫn tốt hơn mọi thứ khác. Vừa thấy ví dụ là tôi đã nghĩ đến Kahan summation hoặc cả một hệ thống đại số máy tính hoàn chỉnh. Tôi chưa từng nghe về Recursive Real Arithmetic
    • Tôi có thêm một góc nhìn về một trong những anh hùng C++ thời kỳ đầu. Nó nhắc tôi rằng những thứ trông đơn giản có thể sâu sắc đến mức nào
  • Giá vé tàu điện ngầm ở NYC là $2.90. Khi tôi dùng PCalc trên iOS để tính số dư còn lại trên MetroCard, nó cho ra -8.881784197E-16 thay vì 0. Điều này không xảy ra khi dùng máy tính của Apple
    • Tôi đã liên hệ với nhà phát triển, và được trả lời rằng Apple dùng thư viện toán học riêng của họ, còn họ thì phải tìm một thư viện khác để thay thế
  • Hầu như không ai làm ra một ứng dụng máy tính hoàn chỉnh. Ý tôi là một máy tính hoàn chỉnh kiểu như TI-89
    • Tôi đang dùng trình giả lập máy tính TI-89 trên Android. Nó thậm chí không có nổi một nửa tính năng của các ứng dụng Android và hoạt động không tốt
  • Nhược điểm của việc chuyển sang RRA không chỉ nằm ở trải nghiệm người dùng. Khi kết quả là 0.0000000..., máy tính không thể quyết định liệu có thể tính nghịch đảo của số đó hay không
    • Ví dụ, 1/(atan(1/5)-atan(1/239)-pi/4) sẽ in ra "không thể tính toán". Thử 1/(atan(1/5)-atan(1/239)-pi/4+10^(-100000)) thì vẫn in ra "không thể tính toán"
  • Gần như mọi con số đều không thể được biểu diễn bằng số thực dấu phẩy động IEEE. Xác suất để một số ngẫu nhiên không thể mô tả được về mặt lý thuyết có thể gần như 100%
    • Một số vấn đề có thể tránh được nếu dùng bignums. Cảm giác bất an hiện sinh thoáng qua đã được xoa dịu
  • Có ai biết các máy tính TI cao cấp, như TI-92, có dùng hệ thống này không? Nó có chế độ "số hữu tỉ", nên có thể đã dùng RRA
  • Cách dùng "recursive real arithmetic" (RRA) khiến tôi nhớ đến một cuộc thảo luận rất hay với Conal Elliot. Chúng tôi đã nói về việc chuyển từ biểu diễn sự vật theo kiểu rời rạc sang biểu diễn liên tục
    • Ví dụ, trước đây phông chữ được biểu diễn bằng các khối pixel, còn bây giờ được nhận thức như các đường nét/vector. Khoa học máy tính không nên chỉ là học các công cụ thương mại mới nhất, mà còn phải là theo đuổi chân lý
  • Tôi đã nghịch thử mã nguồn máy tính của Android Open Source Project. Google đã chuyển nó sang Google Play Services, nhưng mã nguồn cũ vẫn còn dùng được
    • Nó giải quyết được một vài vấn đề thực tế, và tôi hy vọng có thể dùng nó trong thư viện. Trong bài viết trước đã có thảo luận về một vài thư viện