Cho hai số dấu phẩy động, tôi đang tìm cách cách hiệu quả để kiểm tra xem chúng có cùng dấu hiệu không, . của hai giá trị bằng không (+0.0 hoặc -0.0), chúng phải được xem là có cùng một dấu hiệu.Cách so sánh hiệu quả ký hiệu của hai giá trị dấu phẩy động trong khi xử lý các giá trị dấu phẩy động
Ví dụ,
- SameSign (1.0, 2.0) nên trở về đúng
- SameSign (-1.0, -2.0) nên trở về đúng
- SameSign (-1.0, 2.0) nên trả về false
- SameSign (0.0, 1.0) nên trở về đúng
- SameSign (0.0, -1.0) nên trở về đúng
- SameSign (-0,0, 1,0) sẽ trả về đúng
- SameSign (-0,0, -1,0) nên trở về đúng
Một thực hiện ngây thơ nhưng đúng SameSign
trong C++ sẽ là:
bool SameSign(float a, float b)
{
if (fabs(a) == 0.0f || fabs(b) == 0.0f)
return true;
return (a >= 0.0f) == (b >= 0.0f);
}
Giả sử mô hình điểm nổi IEEE, đây là biến thể của SameSign
biên dịch thành mã không có nhánh (ít nhất là với Visual C++ 2008):
bool SameSign(float a, float b)
{
int ia = binary_cast<int>(a);
int ib = binary_cast<int>(b);
int az = (ia & 0x7FFFFFFF) == 0;
int bz = (ib & 0x7FFFFFFF) == 0;
int ab = (ia^ib) >= 0;
return (az | bz | ab) != 0;
}
với binary_cast
được xác định như sau:
template <typename Target, typename Source>
inline Target binary_cast(Source s)
{
union
{
Source m_source;
Target m_target;
} u;
u.m_source = s;
return u.m_target;
}
Tôi đang tìm kiếm hai điều:
Một thực hiện nhanh hơn, hiệu quả hơn
SameSign
, sử dụng thủ đoạn chút, FPU thủ đoạn hoặc thậm chí là bản chất của SSE.Mở rộng hiệu quả
SameSign
thành ba giá trị.
Edit:
Tôi đã thực hiện một số phép đo hiệu suất trên ba biến thể của SameSign
(hai biến thể được mô tả trong câu hỏi ban đầu, cộng với Stephen một). Mỗi hàm được chạy 200-400 lần, trên tất cả các cặp giá trị liên tiếp trong một mảng gồm 101 float được điền một cách ngẫu nhiên với -1.0, -0.0, +0.0 và +1.0. Mỗi phép đo được lặp lại 2000 lần và thời gian tối thiểu được giữ lại (để loại bỏ tất cả các hiệu ứng bộ nhớ đệm và sự chậm lại do hệ thống gây ra). Mã được biên dịch với Visual C++ 2008 SP1 với tối ưu hóa tối đa và tạo mã SSE2 được kích hoạt. Các phép đo được thực hiện trên Core 2 Duo P8600 2.4 Ghz.
Sau đây là các timings, không kể những phí của lấy giá trị đầu vào từ mảng, gọi hàm và lấy kết quả (trong đó số tiền 6-7 clockticks):
- biến Naive: 15 ticks
- Bit biến ma thuật: 13 ticks
- biến Stephens của: 6 ticks
Bất kỳ đặc biệt ngôn ngữ/nền tảng? –
Xin chào, cảm ơn câu hỏi hay :) Tốt hơn là C/C++ trên x86. –
có thể trùng lặp của [so sánh hai phao nổi để xem chúng có phải là số âm hay cả hai đều dương.] (Http://stackoverflow.com/questions/2013680/comparing-two-floats-to-see-if-theyre-both -Negative-hoặc-cả hai-tích cực) – ChrisF