2012-02-28 31 views

Trả lời

4

Dường như chức năng này khá tầm thường; này được dựa trên giả trong câu trả lời chấp nhận cho câu hỏi được liên kết bởi vulkanino:

double value = whatever; 
long bits = BitConverter.DoubleToInt64Bits(value); 
double nextValue = BitConverter.Int64BitsToDouble(bits + 1); 
double result = nextValue - value; 

Đối với phao, bạn cần phải cung cấp thực hiện của riêng bạn SingleToInt32BitsInt32BitsToSingle, vì BitConverter không có những chức năng.

This page hiển thị các trường hợp đặc biệt trong việc triển khai thực hiện hàm java; việc xử lý chúng cũng khá tầm thường.

1

câu trả lời của phoog là tốt nhưng có điểm yếu với số âm, max_double, infinity và NaN.

phoog_ULP (số dương x) -> số dương. Tốt.
phoog_ULP (âm x) -> số âm. Tôi mong đợi con số dương.
Để sửa lỗi này tôi khuyên bạn nên thay vì:

long bits = BitConverter.DoubleToInt64Bits(value) & 0x7FFFFFFFFFFFFFFFL; 

Dưới đây là trường hợp rìa rằng cần giải quyết, bạn nên chăm sóc ...

phoog_ULP (x = +/- Max_double 1,797 ... e + 308) lợi nhuận một kết quả vô hạn. (+1,996 ... e + 292) dự kiến.
phoog_ULP (x = +/- Infinity) dẫn đến NaN. + Infinity dự kiến.
phoog_ULP (x = +/- NaN) bất ngờ có thể thay đổi từ sNan thành qNaN. Không có thay đổi nào được mong đợi. Người ta có thể tranh cãi một trong hai cách trên nếu các dấu hiệu nên trở thành + trong trường hợp này.

Để giải quyết các vấn đề này, tôi chỉ thấy một chuỗi ngắn các thử nghiệm if() tàn bạo để đáp ứng các giá trị "bit" này cho hiệu quả. Ví dụ:

double ulpc(double value) { 
    long long bits = BitConverter::DoubleToInt64Bits(value); 
    if ((bits & 0x7FF0000000000000L) == 0x7FF0000000000000L) { // if x is not finite 
    if (bits & 0x000FFFFFFFFFFFFFL) { // if x is a NaN 
     return value; // I did not force the sign bit here with NaNs. 
     } 
    return BitConverter.Int64BitsToDouble(0x7FF0000000000000L); // Positive Infinity; 
    } 
    bits &= 0x7FFFFFFFFFFFFFFFL; // make positive 
    if (bits == 0x7FEFFFFFFFFFFFFL) { // if x == max_double (notice the _E_) 
    return BitConverter.Int64BitsToDouble(bits) - BitConverter.Int64BitsToDouble(bits - 1); 
    } 
    double nextValue = BitConverter.Int64BitsToDouble(bits + 1); 
    double result = nextValue - value; 
} 
Các vấn đề liên quan