30/09/2018, 17:06

Lấy ra chính xác phần thập phân của số thực

Em cần lấy chính xác giá trị phần thập phân phía sau của 1 số thực, là lấy giá trị luôn chứ không phải in ra đâu ạ.
Đây là đoạn code minh họa, mục đích của em là muốn câu lệnh (fractional == 0.4) ra giá trị true

#include <iostream>
using namespace std;

int main(){
    double a = 2.4;
    double fractional = a - (int)a;
    //double fractional = 0.4;
    cout << (fractional == 0.4) << endl;

    return 0;
}

Lúc debug em mới phát hiện ra là fractional nó là 3.9999999998 chứ không phải 0.4
Mọi người giải thích giùm em và tìm hướng giải quyết bài này với ạ

Mai Anh Dũng viết 19:13 ngày 30/09/2018

Em không lấy được chính xác phần lẻ của số thực được đâu. Về bản chất floatdouble không có độ chính xác không cao. Phần lẻ không đực thể hiện dưới dạng “số” mà thực ra là “số mũ”. Tức thay vì lưu toàn bộ một số xuống bộ nhớ như kiểu int, kiểu double sẽ lưu dữ liệu ở dạng “số mũ”.

Ví dụ đây là cách lưu số 1/3

Given the hexadecimal representation 3FD5 5555 5555 555516,
Sign = 0
Exponent = 3FD16 = 1021
Exponent Bias = 1023 (constant value; see above)
Significand = 5 5555 5555 555516
Value = 2(Exponent − Exponent Bias) × 1.Significand – Note the Significand must not be converted to decimal here
= 2−2 × (15 5555 5555 555516 × 2−52)
= 2−54 × 15 5555 5555 555516
= 0.333333333333333314829616256247390992939472198486328125
≈ 1/3

Xem thêm: http://en.wikipedia.org/wiki/Double-precision_floating-point_format


Double chỉ có thể đúng “tàm tạm” mà thôi. Nếu em muốn so sánh với 0.4 thì ta có thể làm như sau

cout << (fractional == 0.4) << endl;

Tương đương với

cout << (abs(fractional - 0.4) <= 0.0000001) << endl;

Với abs là hàm tính giá trị tuyệt đối của phép trừ (fractional - 0.4). Nếu giá trị này bé hơn hoặc bằng 0.0000001 thì coi như fractional0.4 là bằng nhau.

P/S: Nhớ #include <cmath>

BQC viết 19:09 ngày 30/09/2018

Em cảm ơn anh nhiều ạ

Bài liên quan
0