Greg Hewgill và IllidanS4 đã đưa ra một liên kết với lời giải thích toán học tuyệt vời. Tôi sẽ cố gắng tóm tắt nó ở đây cho những ai không muốn đi quá nhiều vào chi tiết.
Bất kỳ hàm toán học nào, với một số ngoại lệ, đều có thể được biểu diễn bằng một tổng đa thức:
y = f(x)
có thể được chuyển đổi chính xác thành:
y = a0 + a1*x + a2*(x^2) + a3*(x^3) + a4*(x^4) + ...
Trong đó a0, a1, a2, ... là các hằng số . Vấn đề là đối với nhiều hàm, như căn bậc hai, đối với giá trị chính xác, tổng này có vô số phần tử, nó không kết thúc ở một số x ^ n . Nhưng, nếu chúng ta dừng lại ở một số x ^ n, chúng ta vẫn sẽ có một kết quả chính xác đến mức nào đó.
Vì vậy, nếu chúng ta có:
y = 1/sqrt(x)
Trong trường hợp cụ thể này, họ quyết định loại bỏ tất cả các phần tử đa thức ở trên thứ hai, có thể là do tốc độ tính toán:
y = a0 + a1*x + [...discarded...]
Và nhiệm vụ bây giờ là tính toán a0 và a1 để y có sự khác biệt nhỏ nhất so với giá trị chính xác. Họ đã tính toán rằng các giá trị thích hợp nhất là:
a0 = 0x5f375a86
a1 = -0.5
Vì vậy, khi bạn đặt điều này vào phương trình, bạn sẽ nhận được:
y = 0x5f375a86 - 0.5*x
Dòng nào giống với dòng bạn thấy trong mã:
i = 0x5f375a86 - (i >> 1);
Chỉnh sửa: thực ra ở đây y = 0x5f375a86 - 0.5*x
không giống như i = 0x5f375a86 - (i >> 1);
vì chuyển float thành số nguyên không chỉ chia cho hai mà còn chia mũ cho hai và gây ra một số hiện vật khác, nhưng nó vẫn đi xuống để tính một số hệ số a0, a1, a2 ....
Tại thời điểm này, họ phát hiện ra rằng độ chính xác của kết quả này là không đủ cho mục đích. Vì vậy, họ cũng chỉ thực hiện một bước lặp lại Newton để cải thiện độ chính xác của kết quả:
x = x * (1.5f - xhalf * x * x)
Họ có thể đã thực hiện thêm một số lần lặp trong một vòng lặp, mỗi lần một cải thiện kết quả, cho đến khi đáp ứng được độ chính xác cần thiết. Đây chính xác là cách nó hoạt động trong CPU / FPU! Nhưng có vẻ như chỉ một lần lặp lại là đủ, đó cũng là một may mắn cho tốc độ. CPU / FPU thực hiện nhiều lần lặp lại nếu cần để đạt được độ chính xác cho số dấu phẩy động trong đó kết quả được lưu trữ và nó có thuật toán chung hơn hoạt động cho mọi trường hợp.
Tóm lại, những gì họ đã làm là:
Sử dụng (gần như) cùng một thuật toán với CPU / FPU, khai thác việc cải thiện các điều kiện ban đầu cho trường hợp đặc biệt của 1 / sqrt (x) và không tính toán tất cả các cách để CPU / FPU chính xác sẽ đi đến nhưng dừng sớm hơn, do đó tăng tốc độ tính toán.