2017-02-21 12 views
9

Tôi có phương pháp sau để nhân hai số 32 bit ở định dạng 19.13 cố định. Nhưng tôi nghĩ rằng có vấn đề với phương pháp này:Nhân số điểm cố định của số âm

1.5f được làm tròn thành 2.0f, trong khi -1.5f được làm tròn thành -1.0f.

Dường như với tôi rằng -1.5 phải được làm tròn xuống -2.0f.

Đầu tiên, hình thức làm tròn hiện tại có hợp lý không và làm cách nào để thay đổi nó để nhất quán hơn?

static OPJ_INT32 opj_int_fix_mul(OPJ_INT32 a, OPJ_INT32 b) { 
    OPJ_INT64 temp = (OPJ_INT64) a * (OPJ_INT64) b ; 
    temp += 4096; 
    assert((temp >> 13) <= (OPJ_INT64)0x7FFFFFFF); 
    assert((temp >> 13) >= (-(OPJ_INT64)0x7FFFFFFF - (OPJ_INT64)1)); 
    return (OPJ_INT32) (temp >> 13); 
} 

Trả lời

5

Vì bạn luôn thêm 4096, mã đang thực hiện làm tròn các trường hợp nửa chừng về hướng vô cùng tích cực. Nó là loại kỳ quặc.

Để làm tròn về phía dương vô cực, tôi mong đợi

temp += 4096 + 4095; 

Để làm tròn theo kiểu thông thường (gần nhất), sử dụng thay vì thêm một sự thiên vị ra khỏi 0.

temp += (temp < 0) ? -4096 : 4096; 

Để làm tròn các mối quan hệ gần nhất và thậm chí còn hiệu quả hơn. Không nhất định OP mong muốn điều đó.

Các vấn đề liên quan