Trong ngữ cảnh phân tích tĩnh, tôi quan tâm đến việc xác định giá trị của x
trong nhánh sau của điều kiện dưới đây:Thuật toán nhanh nhất để xác định x nhỏ nhất và lớn nhất tạo phương trình chính xác kép x + a == b true
double x;
x = …;
if (x + a == b)
{
…
a
và b
có thể được giả định là hằng đúp chính xác (khái quát hóa để biểu thức tùy ý là phần dễ nhất của vấn đề), và trình biên dịch có thể được giả định theo chuẩn IEEE 754 nghiêm (FLT_EVAL_METHOD
là 0). Chế độ làm tròn tại thời gian chạy có thể được giả định là gần nhất.
Nếu tính toán với lý trí rẻ, nó sẽ đơn giản: các giá trị cho x
sẽ là số chính xác kép có trong khoảng thời gian hợp lý (b - a - 0.5 * ulp1 (b)… b - a + 0.5 * ulp2 (b)). Các giới hạn nên được bao gồm nếu b
thậm chí bị loại trừ nếu b
là lẻ, và ulp1 và ulp2 là hai định nghĩa hơi khác nhau của "ULP" có thể được lấy giống hệt nhau nếu không nhớ mất một chút chính xác về sức mạnh của hai.
Thật không may, tính toán với hợp lý có thể tốn kém. Xem xét khả năng khác là thu được từng giới hạn bằng cách phân đôi, trong 64 phép cộng hai lần chính xác (mỗi thao tác quyết định một bit kết quả). 128 bổ sung dấu phẩy động để có được giới hạn dưới và trên có thể nhanh hơn bất kỳ giải pháp nào dựa trên toán học.
Tôi tự hỏi liệu có cách nào cải thiện ý tưởng “bổ sung 128 điểm nổi” hay không. Trên thực tế, tôi có giải pháp riêng của mình liên quan đến các thay đổi về chế độ làm tròn và các cuộc gọi nextafter
nhưng tôi không muốn làm hỏng phong cách của bất kỳ ai và khiến họ bỏ lỡ một giải pháp thanh lịch hơn so với giải pháp hiện tại của tôi. Ngoài ra tôi không chắc chắn rằng việc thay đổi chế độ làm tròn hai lần thực sự rẻ hơn 64 điểm bổ sung nổi.
Bạn có thể sử dụng tìm kiếm nhị phân để chia đôi các giá trị bạn muốn không? Nó sẽ có vẻ như thế này nên có thể vì số lượng bit thấp. – templatetypedef
@templatetypedef giải pháp “128 điểm bổ sung” mà tôi phác họa là tìm kiếm nhị phân trên biểu diễn các số dấu phẩy động và một số mà tôi không muốn hiển thị vì tôi không biết nếu nó thực sự là cải tiến làm giảm khoảng thời gian ban đầu để chia đôi bằng cách tính toán một phạm vi gần đúng của các ứng cử viên, mà sau đó sẽ cần phải được tinh chỉnh bằng tìm kiếm nhị phân. –
@templatetypedef Tôi là loại hy vọng rằng ai đó sẽ đưa ra một định lý của arithmetics nổi điểm mà giải quyết vấn đề thanh lịch hơn. –