🌱 Tổng quan về Dấu phẩy động - Floating Point

🌱 Tổng quan về Dấu phẩy động - Floating Point

    Trong lập trình nói chung và lập trình C nhúng nói riêng, chúng ta đã biết về kiểu dữ liệu số thực (float). Đối với số nguyên thông thường, dễ thấy chúng có thể biểu diễn dưới dạng nhị phân trên bộ nhớ bằng cách chuyển đổi decimal-binary, vậy còn số thực sẽ biểu diễn dưới dạng nhi phân như thế nào? Bài viết dưới đây sẽ cùng các bạn tìm hiểu về điều đó.

    Bài viết sẽ giới thiệu về các thuật ngữ chính về biểu diễn dấu phẩy động, dựa trên tiêu chuẩn IEEE 754, giới hạn trong single và double precision formats (Độ chính xác đơn và kép).

    👉 Cách biểu diễn dấu phẩy động theo chuẩn IEEE 754

    Dễ thấy, giống như số nguyên, các số thực (float) sẽ được biểu diễn dưới dạng binary trên bộ nhớ (tức các bit 0 và 1). Vậy, đơn giản nhất thì một số thực sẽ biểu diễn dưới dạng sau:

ImIm-1…I2I1I0.F1F2…FnFn-1

    Trong đó, Im và Fsẽ là các bit 0 hoặc 1, lần lượt biểu diễn cho phần nguyên (integer) và phần thực (fraction).

    Một số hữu hạn có thể được biểu diễn bằng 4 thành phần số nguyên như sau:

  • Bit dấu (s - sign), cơ số (b - base), phần giá trị có nghĩa (m - significant)số mũ (e - exponent).
  • Giá trị của số đó sẽ là:
(-1)s x m x be ________ Where m < |b|

    Tùy thuộc vào base và số lượng bit được sử dụng để mã hóa các thành phần khác nhau, tiêu chuẩn IEEE 754 định nghĩa ra 5 formats cơ bản. Trong đó, binary32 và binary64 formats là single precision (Độ chính xác đơn) và double precision (Độ chính xác kép) formats, với base là 2.

PrecisionBaseSignExponentSignificant
Single precision21823+1
Double precision211152+1

    👉 Biểu diễn Single Precision Format

    Như bản trên đề cập thì Single Precision Format sẽ dành 23-bits cho significant (1 represent implied bit), 8-bits cho số mũ exponent, 1-bit dấu (sign).

numeric

    Ví dụ, số 9/2 = 4.5 có thể được biểu diễn dưới dạng nhị phân, theo Single precision format như sau:

4.5 = 4 + 0.5 = 4 + 1/2
4 = 100
1/2 = 1
Chuyển sang dạng binary : 4.5 = 100.1 = 1.001 * 2^2
Mantissa (phần sau dấu phẩy) = 00100000000000000000000
Exponent (số mũ) = 2, sẽ cần cộng thêm 127
Exponent = 2 + 127 = 129d = 10000001b
Số dương nên signed bit = 0
Theo chuẩn IEEE 754, biểu diễn của số 4.5 dưới dạng nhị phân sẽ là:
0 10000001 00100000000000000000000 = 0x40900000

    Dễ dàng kiểm chứng dạng hexa của một số float bằng cách sử dụng Union trong C như sau:

#include <stdio.h>
#include <stdint.h>

typedef union
{
    float floatingpoint;
    uint32_t integer;
} NumType;

int main()
{
    NumType Test;
    Test.floatingpoint = 4.5;
printf("Hexa format = 0x%x", Test.integer); }     Run This Code    

    Dễ thấy 2 phần tử floatingpointinteger của union NumType sẽ dùng chung bộ nhớ là 32-bits, nên khi in ra phần tử integer dưới dạng hexa cũng chính là in ra phần tử  floatingpoint dưới dạng hexa.

    ➥ Các bạn có thể bấm "Run This Code", kết quả hiển thị trên màn hình console như sau.

Hexa format = 0x40900000


    👉 Biểu diễn Double Precision Format

    Như đã đề cập ở bảng trên, Double Precision Format sẽ dành 52-bits cho significant (1 represent implied bit), 11-bits cho số mũ exponent, 1-bit dấu (sign).

float

    Cách biến đổi sang dạng binary sẽ tương tự như cách biểu diễn Single Precision Format, các bạn cũng có thể làm tương tự như cách dùng union trên để kiểm chứng với 2 kiểu dữ liệu là doubleuint64 trong C.

    👉 Kết luận

    Dễ thấy với chuẩn IEEE 754, floating point được biểu diễn dưới dạng binary theo một các khá dễ hiểu và rải giá trị khá lớn. Vì vậy, hầu hết các ngôn ngữ lập trình đều cung cấp floating point với cách biểu diễn theo chuẩn IEEE 754.

    Tuy nhiên, biểu diễn floating point cũng có một số điểm hạn chế như:

  • Cách biểu diễn dễ hiểu với người dùng nhưng khá phức tạp với máy tính, đặc biệt khi tính toán, dẫn đến việc tính toán trên số thực float sẽ có tốc độ thường chậm hơn so với số nguyên.
  • Lỗi làm tròn số: Biểu diễn floating point có thể dẫn đến sai sót làm tròn (Có thể dễ dàng kiểm chứng bằng các so sánh float a = 1; với số 1.0).

    Ở bài viết sau, mình sẽ cùng bạn tìm hiểu về các tính toán số floating point trong các kiến trúc máy tính và vi điều khiển, cũng như cách hardware support việc tính toán số floating point như thế nào!

>>>= Follow ngay =<<<

Để theo dõi những bài học miễn phí mới nhất nhé 😊

Chúc các bạn học tập tốt 😊

                                        

Nguyễn Văn Nghĩa

Mình là một người thích học hỏi và chia sẻ các kiến thức về Nhúng IOT.

Đăng nhận xét

Mới hơn Cũ hơn