Số thực dấu phẩy động

Trong tin học, **dấu phẩy động** được dùng để chỉ một hệ thống biểu diễn số mà trong đó sử dụng một chuỗi chữ số (hay bit) để biểu diễn một số hữu tỉ.

Thuật ngữ *dấu phẩy động* xuất phát từ chỗ hệ thống dấu phẩy động có dấu phẩy cơ số (tức là dấu phẩy thập phân trong trường hợp dùng hệ thập phân thường ngày hoặc là dấu phẩy nhị phân trong trường hợp dùng bên trong máy tính) không cố định mà có thể thay đổi vị trí của nó bất kỳ đâu trong các chữ số có nghĩa của số cần được biểu diễn. Vị trí này được mô tả một cách độc lập trong biểu diễn cụ thể của từng số. Đã có nhiều hệ thống dấu phẩy động khác nhau được dùng trong máy tính; tuy nhiên, vào khoảng hai mươi năm trở lại đây thì hầu hết các máy tính đều dùng cách biểu diễn tuân thủ theo chuẩn IEEE 754.

Một điều cần lưu ý là có sự khác biệt khi gọi tên dấu phẩy cơ số: ở Việt Nam, chúng ta dùng dấu phẩy để ngăn cách giữa phần nguyên và phần thập phân; trong khi các nước như Mỹ, Anh,...dùng dấu chấm để làm điều này. Chính vì thế, thuật ngữ tương ứng với dấu phẩy động ở tiếng Anh là floating point mà dịch sát ra tiếng Việt phải là dấu chấm động. Các phần sau, ta vẫn dùng thuật ngữ dấu phẩy động nhưng khi biểu diễn các số trong ví dụ thì vẫn mô tả theo quy ước của các nước nói trên (mà cũng là quy ước chuẩn dùng trong máy tính), nghĩa là vẫn dùng dấu chấm thay cho dấu phẩy.

Ưu điểm của cách biểu diễn dấu phẩy động là nó cho phép biểu diễn một tầm giá trị rộng hơn nhiều so với cách biểu diễn dấu phẩy tĩnh. Lấy ví dụ, nếu cách biểu diễn dấu phẩy tĩnh có bảy chữ số thập phân với quy ước dấu phẩy thập phân luôn nằm cố định ở chữ số thứ năm, thì cách biểu diễn dấu phẩy tĩnh có thể mô tả các số như 12345.67, 8765.43, 123.00 (tức 00123.00) và vân vân. Trong khi đó cách biểu diễn dấu phẩy động (chẳng hạn như định dạng decimal32 của IEEE 754) với bảy chữ số thập phân ngoài việc mô tả được các số nói trên còn mô tả được nhiều số khác mà dấu phẩy tĩnh không mô tả được như 1.234567, 123456.7, 0.00001234567, 1234567000000000, và nhiều nữa. Tất nhiên, định dạng theo kiểu dấu phẩy động cần thêm bộ nhớ hơn so với dấu phẩy tĩnh (vì cần có thêm bộ nhớ để mô tả vị trí của dấu phẩy cơ số), nhưng ta có thể nói: với cùng một không gian bộ nhớ, cách biểu diễn dấu phẩy động đạt được tầm mô tả rộng hơn.

Tốc độ các phép toán làm việc với số dấu phẩy động là một thước đo quan trọng nhằm đánh giá khả năng của một máy tính trong nhiều ứng dụng khác nhau. Đơn vị đo về tốc độ này là FLOPS.

## Tổng quan
Một cách biểu diễn số (gọi là hệ thống ký số trong toán học) bao gồm phương pháp dùng để lưu trữ một con số bằng một chuỗi các chữ số. Số học được định nghĩa là tập hợp các thao tác cần làm trên cách biểu diễn số đã cho để thực hiện các phép toán số học (cộng, trừ, nhân, chia...).

Có một số cách dùng chuỗi các chữ số để biểu diễn các con số. Theo ký hiệu toán học thông dụng, chuỗi chữ số có thể có chiều dài tùy ý, và vị trí của dấu phẩy cơ số được chỉ ra bằng cách đặt một ký tự rõ ràng (đó là dấu chấm đối với các nước Anh, Mỹ... hoặc là dấu phẩy đối với Việt Nam). Trong trường hợp chuỗi chữ số không có dấu phẩy thì nó được xem như đặt ở phía cuối bên phải của chuỗi chữ số (tức là, số đang biểu diễn là một số nguyên). Trong trường hợp máy tính thì với chỉ hai bit 0 và 1, không thể có một ký tự rõ ràng phân biệt để mô tả dấu phẩy. Trong hệ thống dấu phẩy tĩnh, người ta quy ước vị trí cố định của dấu phẩy cơ số trong chuỗi chữ số. Lấy ví dụ, quy ước rằng chuỗi chữ số gồm 8 chữ số thập phân và dấu phẩy thập phân luôn nằm ở ngay giữa chuỗi thì khi đọc giá trị "00012345" ta phải ngầm hiểu đây là số có giá trị 1.2345.

Trong ký hiệu khoa học, một con số thường được lấy tỉ lệ (tức được nhân) với một lũy thừa của 10 sao cho kết quả sau khi lấy tỉ lệ nằm trong một tầm cho trước – điển hình là nằm trong khoảng 1 và 10, tức là kết quả sẽ được viết ra với dấu phẩy cơ số nằm trực tiếp sau chữ số đầu tiên. Để người đọc có thể biết giá trị thực của con số, lũy thừa của 10 sẽ được viết riêng ra ở cuối kết quả. Lấy ví dụ, chu kỳ xoay mặt trăng Io của hành tinh Mộc Tinh là 152853.5047 giây. Khi đó, con số này được biểu diễn dưới dạng ký hiệu khoa học chuẩn là 1.528535047 giây.

Cách biểu diễn số dấu phẩy động tương tự với cách dùng trong ký hiệu khoa học. Mô tả luận lý thì một số dấu phẩy động bao gồm:

* Một chuỗi chữ số có dấu với chiều dài cho trước và có cơ số cho trước. Chuỗi này được gọi là phần định trị. Dấu phẩy cơ số không được thể hiện tường minh ở phần này, nhưng được quy ước ngầm là luôn luôn nằm tại một vị trí cụ thể trong phần định trị - mà thường là ngay sau hoặc ngay trước chữ số có nghĩa lớn nhất. Bài viết này nếu không nói rõ sẽ tuân theo quy ước là dấu phẩy cơ số luôn ở ngay sau chữ số có nghĩa lớn nhất (tức là chữ số đầu tiên tính từ bên trái qua). Độ dài của phần định trị xác định độ chính xác mà các con số có thể được biểu diễn.
* Một số mũ là số nguyên có dấu, nhằm mô tả phần lấy tỉ lệ tức cho phép người đọc xác định được giá trị thực của số từ phần định trị.

Thử lấy một ví dụ ở cơ số 10 (hệ thập phân mà ta thường dùng hằng ngày) với số 152853.5047 mà có độ chính xác là mười chữ số thập phân. Khi biểu diễn dưới dạng dấu phẩy động thì nó sẽ được viết với phần định trị là 1528535047 (với quy ước là vị trí của dấu phẩy cơ số nằm ngay sau chữ số có nghĩa lớn nhất, tức là chữ số 1). Khi đó, phần định trị được hiểu ngầm là 1.528535047. Để người đọc có thể khôi phục lại giá trị ban đầu thì cần phải thêm số mũ là 5. Khi đó, người đọc sẽ nhân giá trị của phần định trị (sau khi đã thêm dấu phẩy cơ số vào vị trí quy ước) với 105 để được 1.528535047 × 105, hay 152853.5047.

Mô tả hình thức thì giá trị cuối cùng của một số dấu phẩy động là

:s \times b^e

với *s* là giá trị của phần định trị (sau khi đã đặt dấu phẩy cơ số vào vị trí quy ước), *b* là cơ số, và *e* là số mũ.

Hoàn toàn tương đương, có thể viết công thức trên như sau:
: \frac{S}{b^{p-1}} \times b^e
với *S* là giá trị nguyên của toàn bộ phần định trị mà chưa đặt dấu phẩy cơ số và *p* là độ chính xác – số chữ số của phần định trị.

Khi dùng cách biểu diễn dấu phẩy động, phương pháp lưu trữ phần định trị, số mũ và bit dấu bên trong máy tính tùy thuộc vào mỗi loại máy theo chuẩn nào. Hiện nay, chuẩn IEEE 754 là thông dụng nhất sẽ được mô tả ở phần sau. Nhưng ở đây, chúng ta thử xét định dạng nhị phân độ chính xác đơn (32 bit) của IEEE754. Theo chuẩn này thì một số dấu phẩy động định dạng độ chính xác đơn sẽ có 32 bit bao gồm: 1 bit dấu, 23 bit cho phần định trị và 8 bit cho phần số mũ.Lấy ví dụ, 33 bit đầu tiên của số π là 11.001001 00001111 11011010 10100010 0 (lưu ý dấu phẩy cơ số nằm ở sau bit 1 thứ hai từ bên trái qua). Để biểu diễn số π này ở định dạng IEEE 754 độ chính xác đơn, ta phải làm tròn chuỗi bit nói trên còn 24 bit (tại sao lại là 24 bit trong khi phần định trị của định dạng chính xác đơn chỉ có 23 bit sẽ được giải thích ngay sau đây). Để làm tròn như vậy, ta kết hợp các giá trị của bit thứ 24 và bit thứ 25 để được giá trị 11.001001 00001111 11011011. Yêu cầu của chuẩn IEEE 754 là phần định trị phải có giá trị nằm trong khoảng từ 1 đến 2 (tức là chuẩn IEEE 754 quy ước dấu chấm cơ số luôn luôn nằm ngay sau bit 1 đầu tiên). Chính vì thế ta phải lấy tỉ lệ kết quả làm tròn thành 1.1001001 00001111 11011011với số mũ *e*&nbsp;=&nbsp;1. Đến đây, vì bit đầu tiên (và cũng là duy nhất) đứng trước dấu phẩy cơ số của phần định trị luôn luôn là 1 nên ta không cần lưu trữ bit này và viết gọn phần định trị là 1001001 00001111 11011011. Khi đó, số bit của phần định trị chỉ còn 23 bit khớp với số bit được chuẩn IEEE 754 dùng cho phần định trị. Để xác định giá trị của π, ta dùng công thức
:(1+\sum_{n=1}^{p-1} bit_n\times 2^{-n})\times 2^e=(1+1\times 2^{-1}+0\times 2^{-2}+1\times 2^{-4}+1\times2^{-7}+\dots +1\times 2^{-23})\times 2^1=1.5707964\times 2
với n là bit thứ n của phần định trị. Quá trình lấy tỉ lệ phần định trị sao cho giá trị của nó phải nằm trong khoảng từ 1 đến 2 và bỏ không lưu trữ bit 1 đầu tiên được gọi là *chuẩn hóa*. Ta có thể xem việc chuẩn hóa giống như một dạng của nén; nó cho phép ta thực hiện lưu trữ 24 bit định trị trong một trường chỉ có 23 bit với lưu ý rằng luôn luôn có một bit 1 ở trước dấu phẩy cơ số.

### Một số cách khác dùng để biểu diễn số không nguyên trong máy tính
Biểu diễn dấu phẩy động nói chung, đặc biệt định dạng chuẩn IEEE, hiện nay và trong tương lai gần vẫn là phương pháp cho phép lưu trữ trong máy tính giá trị xấp xỉ các số thực bởi vì nó được sử dụng hiệu quả trong hầu hết các bộ vi xử lý máy tính. Tuy nhiên, vẫn có những phương pháp khác:
* Cách biểu diễn dấu phẩy tĩnh dùng phần cứng làm việc với các số nguyên với phần mềm quy định vị trí cụ thể của dấu phẩy thập phân hay nhị phân, chẳng hạn, quy định rõ dấu phẩy nằm ở ngay sau 6 bit hay 6 chữ số kể từ bên phải. Phần cứng thực hiện trên cách biểu diễn này đơn giản hơn so với phần cứng cần có trong dấu phẩy động và thông thường được dùng để thực thi các phép toán số nguyên. Đặc biệt, dấu phẩy tĩnh nhị phân thường được dùng trong những ứng dụng riêng biệt trên các bộ vi xử lý nhúng mà chỉ cần làm các phép toán số học nguyên, còn dấu phẩy tĩnh thập phân thì thường dùng trong các ứng dụng thương mại.
* Mã BCD là một cách mã hóa các số thập phân bằng cách thay mỗi chữ số thập phân bằng một dãy số nhị phân đại diện cho chữ số đó.
* Khi cần độ chính xác cao hơn, các phép toán cho dấu phẩy động có thể được sửa đổi bằng phần mềm sao cho phần định trị của dấu phầy động có thể thay đổi chiều dài tức có thể tăng hay giảm tùy theo phần mềm. Phương pháp này gọi là độ chính xác thay đổi, hay còn gọi là số học "bignum có tỉ lệ".
* Các hệ thống số học máy tính chẳng hạn như Mathematica, Maple và Maxima thường cho phép làm việc trên các số vô tỉ như \pi hay \sqrt{3} theo một kiểu hình thức nghĩa là giống như ta làm việc với một ký hiệu toán học thuần túy mà không cần phải chuyển các số nói trên ra dạng gần đúng dấu phẩy động. Những phần mềm như vậy có thể tính toán các biểu thức chẳng hạn như "\sin 3\pi" một cách chính xác, bởi vì chúng được lập trình để "hiểu" ý nghĩa toán học của các ký hiệu này.
* Một cách biểu diễn nữa dựa trên logarith tự nhiên mà đôi khi được dùng trong những ứng dụng dựa trên FPGA mà trong đó hầu hết các phép toán số học cần làm là toán nhân và toán chia. Giống như biểu diễn dấu phẩy động, cách biểu diễn này cho độ chính xác tốt hơn trong trường hợp các toán hạng nhỏ hơn cũng như có tầm biểu diễn rộng hơn.

## Tầm biểu diễn của các số dấu phẩy động
Bằng cách cho phép vị trí của dấu phẩy cơ số điều chỉnh được, cách biểu diễn dấu phẩy động giúp người sử dụng thực hiện các phép toán trên một tầm rộng về biên độ ứng với một số cố định chữ số mà vẫn duy trì được độ chính xác tốt. Ví dụ, trong hệ thống dấu phẩy động thập phân có phần định trị là ba chữ số và phần mũ là một chữ số (tổng cộng tài nguyên hiển thị cho một con số là 4 chữ số), phép nhân mà con người chúng ta thường viết 
:0.12 × 0.12 = 0.0144
sẽ được mô tả ở dạng dấu phẩy động như sau:
:(1.20) × (1.20) = (1.44).
Nếu thực hiện phép nhân nói trên trong một hệ thống dấu phẩy tĩnh có tài nguyên hiển thị là 4 chữ số với quy ước dấu phẩy thập phân luôn ở phía sau chữ số đầu tiên bên trái thì kết quả sẽ là 
:0.120 × 0.120 = 0.014.
Rõ ràng một chữ số của kết quả sẽ bị mất đi do chỉ có 4 chữ số để hiển thị và quan trọng hơn là dấu phẩy thập phân không linh hoạt, bị quy ước cố định trong dãy chữ số. 
Tầm hiển thị của số dấu phẩy động phụ thuộc vào số bit hay số chữ số của phần định trị và của phần số mũ. Trên hệ thống máy tính thông thường, một số dấu phẩy động nhị phân định dạng 'độ chính xác kép' (64 bit) có phần định trị 52 bit (thực ra là 53 bit vì trong đó có một bit 1 luôn luôn có nhưng không thể hiện tường minh, điều này cũng giống định dạng độ chính xác đơn đã trình bày ở trên), phần số mũ gồm 11 bit và 1 bit dấu. Tầm số dương mà định dạng này có thể biểu diễn được là khoảng từ 10−308 đến 10308 (vì 308 xấp xỉ bằng 1023 × log10(2) và tầm số mũ của định dạng độ chính xác kép là [−1023,1024]). Toàn tầm hiển thị của định dạng độ chính xác kép là khoảng từ −10308 đến +10308 (xem IEEE754).

Một hệ thống số dấu phẩy động F(b, p, l, u) (ở đây b là cơ số của hệ thống, p là độ chính xác của hệ thống – tức là số chữ số có trong phần định trị kể cả bit không hiển thị tường minh nhưng ngầm hiểu, l và u lần lượt là số mũ nhỏ nhất và lớn nhất mà hệ thống có thể biểu diễn được) có thể biểu diễn được một số lượng các con số chuẩn hóa theo công thức sau:

2 * (b-1)* b^{p-1} * (u-l+1)

Có một số dương nhỏ nhất trong các số dấu phẩy động chuẩn hóa và được gọi là mức tràn dưới (underflow level) = UFL = b^l. UFL có bit 1 (không hiển thị tường minh và hiểu ngầm) ở vị trí trước dấu chấm cơ số của phần định trị, các bit còn lại của phần định trị bằng 0 và phần mũ có giá trị nhỏ nhất.

Có một số dương lớn nhất trong các số dấu phẩy động chuẩn hóa và được gọi là mức tràn trên (overflow level) = OFL = b^(u+1) * (1-b^(-p)). OFL có giá trị mỗi chữ số ở phần định trị đều bằng (b-1) và phần mũ có giá trị lớn nhất.

Hơn nữa, còn có những giá trị mà hệ thống dấu phẩy động có thể biểu diễn được. Đó là một số giá trị nằm giữa –UFL và UFL. Các số này là zero, zero âm, cũng như các số không chuẩn hóa.

## Lịch sử
Năm 1938, nhà phát minh Konrad Zuse ở Berlin đã tạo ra "Z1", máy tính cơ lập trình được nhị phân đầu tiên. Máy tính này làm việc trên các số dấu phẩy động 22 bit gồm phần mũ 7 bit, phần định trị 15 bit (gồm cả bit không hiển thị tường minh và hiểu ngầm mà từ đây về sau ta gọi đó là bit ẩn), và 1 bit dấu. Máy tính Z3 được hoàn thành năm 1941, thực hiện được các phép toán số học dấu phẩy động kể cả trường hợp đặc biệt bao gồm kết quả vô cực dương, vô cực âm và không xác định.
Ngay khi máy tính số điện tử trở thành hiện thực thì nhu cầu xử lý dữ liệu theo kiểu dấu phẩy động đã nhanh chóng phát sinh. Máy tính thương mại đầu tiên có khả năng làm điều này trong phần cứng là máy Z4 được sản xuất năm 1950, sau đó là máy tính IBM 704 trong năm 1954. Khoảng thời gian sau đó, phần cứng xử lý được dấu phẩy động là một đặc tính kỹ thuật tùy chọn và những máy tính nào mà có phần cứng này được gọi là "máy tính khoa học", hay được gọi là có khả năng "tính toán khoa học". Ngày nay thì tất cả máy tính đa dụng đều có khả năng đó. Máy tính hiệu PDP-11/44 mà là một phiên bản mở rộng của 11/34 có bộ nhớ cache và phần xử lý dấu phẩy động như là bộ phận chuẩn của nó.

Dòng máy tính UNIVAC 1100/2200 được giới thiệu năm 1962, cho phép làm việc với hai định dạng dấu phẩy động. Định dạng độ chính xác đơn dùng 36 bit, tổ chức thành 1 bit dấu, 8 bit phần mũ và 27 bit phần định trị. Định dạng độ chính xác kép dùng 72 bit tổ chức thành 1 bit dấu, 11 bit phần mũ và phần định trị 60 bit. Máy tính IBM 7094 được giới thiệu cùng năm, cũng cho phép làm việc với định dạng độ chính xác đơn và độ chính xác kép nhưng có cách tổ chức hơi khác.
Trước khi có chuẩn IEEE 754, các máy tính dùng nhiều dạng dấu phẩy động khác nhau. Những định dạng này khác nhau về chiều dài bit, cách hiển thị và cách làm tròn ở các phép toán. Những khác biệt này dẫn đến những phần khác nhau về số học trong cả phần cứng lẫn phần mềm, và có độ chính xác khác nhau.
Chuẩn IEEE-754 ra đời vào đầu thập niên 1980, dẫn đến việc dùng chiều dài 32 bit (hay 16 hay 64 bit) trở nên được thừa nhận. Một số đặc điểm của chuẩn này:
* Đưa ra một cách cụ thể mã hóa các bit sao cho tất cả những máy tính tuân thủ với chuẩn này đều hiểu chuỗi bit như nhau. Điều này cho phép có thể truyền các số dấu phẩy động từ máy tính này đến máy tính khác.
* Đưa ra một cách cụ thể cách ứng xử của các phép toán số học. Điều này có nghĩa là với một chương trình cho trước, với dữ liệu cho trước, luôn luôn phải tạo ra được cùng một kết quả trên bất kỳ máy tính nào tuân thủ với chuẩn này. Điều này làm giảm đi những đánh giá tai tiếng khó hiểu rằng tính toán trên dấu phẩy động sẽ cho ra những kết quả lung tung, khó xác định.
* Các khả năng sinh ra các điều kiện đặc biệt (tràn, chia cho zero,v..v) được xác định trong suốt quá trình tính toán một cách rõ ràng và có thể kiểm soát được bằng phần mềm theo một cách chặt chẽ.

## IEEE 754: chuẩn dấu phẩy động trong máy tính ngày nay

Hiệp hội IEEE đã chuẩn hóa cho việc biểu diễn số dấu phẩy động nhị phân trong máy tính bằng cách đưa ra chuẩn IEEE 754. Ngày nay hầu hết các máy tính đều tuân thủ theo chuẩn này. Một số trường hợp ngoại lệ như máy tính lớn IBM và máy vector Cray. Loại máy tính lớn IBM ngoài định dạng thập phân và nhị phân IEEE 754 còn có một định dạng riêng của IBM. Còn với máy vector Cray thì họ T90 có một phiên bản IEEE nhưng máy SV1 vẫn còn dùng định dạng dấu phẩy động của chính Cray.

Chuẩn IEEE 754 đưa ra nhiều định dạng rất gần nhau, chỉ khác nhau ở một ít chi tiết. Năm trong số những định dạng này được gọi là *định dạng cơ bản*, và hai trong chúng đặc biệt được dùng rộng rãi trong cả phần cứng máy tính và ngôn ngữ lập trình:
* Độ chính xác đơn, được gọi bằng tên là "float" trong họ ngôn ngữ lập trình C và tên là "real" hay "real*4" trong ngôn ngữ Fortran. Đây là định dạng nhị phân chiếm 32 bit (4 byte) và phần định trị của nó có độ chính xác 24 bit (tương đương với khoảng 7 chữ số thập phân).
* Độ chính xác kép, được gọi bằng tên là "double" trong họ ngôn ngữ lập trình C và tên là "double precision" hay "real*8" trong ngôn ngữ Fortran. Đây là định dạng nhị phân chiếm 64 bit (8 byte) và phần định trị của nó có độ chính xác 53 bit (tương đương với khoảng 16 chữ số thập phân).

Các định dạng khác là nhị phân với độ chính xác bậc bốn (128 bit), cũng như là dấu phẩy động thập phân (64 bit) và dấu phẩy động thập phân "kép" (128 bit).

Các định dạng ít thông dụng hơn:
* Định dạng độ chính xác mở rộng, mỗi số chiếm 80 bit.
* Định dạng bán chính xác cũng gọi là dấu phẩy động 16, mỗi số chiếm 16 bit.
Bất kỳ một số nguyên nào có giá trị tuyệt đối nhỏ hơn hay bằng 224 đều có thể biểu diễn một cách chính xác bằng định dạng độ chính xác đơn, và bất kỳ số nguyên nào có giá trị tuyệt đối nhỏ hơn hay bằng 253 cũng có thể biểu diễn một cách chính xác bằng định dạng độ chính xác kép.

Mặc dầu các định dạng 32 bit ("đơn") và 64 bit ("kép") hiện nay là phổ biến, nhưng chuẩn IEEE 754 cũng cho phép nhiều mức chính xác khác nhau. Lấy ví dụ, các phần cứng máy tính như họ Pentium Intel và họ 68000 Motorola thường có thêm định dạng độ chính xác mở rộng 80 bit, với phần mũ 15 bit, phần định trị 64 bit (không có bit ẩn) và 1 bit dấu. Một dự án nhằm mục đích sửa đổi chuẩn IEEE 754 đã được khởi động trong năm 2000 (xem IEEE 754 sửa đổi. Dự án này đã hoàn thành và được công nhận vào tháng 6 năm 2008. Nó bao gồm các định dạng dấu phẩy động thập phân và định dạng dấu phẩy động 16 bit ("nữa"). Định dạng 16 bit nhị phân có cùng cấu trúc và quy luật như các định dạng cũ khác với 1 bit dấu, phần mũ 5 bit và 10 bit phần định trị. Định dạng này hiện đang được sử dụng trong ngôn ngữ đồ họa Cg của NVIDIA, và có mặt trong chuẩn mở EXR.

### Cấu trúc biểu diễn bên trong máy tính
Thông thường thì các số dấu phẩy động được thể hiện trong bộ nhớ máy tính theo thứ tự từ trái sang phải gồm bit dấu, phần mũ, rồi đến phần định trị. Với định dạng nhị phân IEEE 754 chúng thường được biểu diễn bằng các phần sau:

Cần lưu ý rằng phần mũ có giá trị âm hay dương, nhưng khi lưu trữ trong máy tính người ta không dùng hệ bù 2 để biểu diễn phần mũ mà lại sử dụng một phương pháp khác: biểu diễn phần mũ dưới dạng một số không dấu nhưng có một giá trị "phân cực" cố định thêm vào. Lấy ví dụ, với định dạng độ chính xác đơn thì giá trị phân cực bằng +127, có nghĩa là để biểu diễn giá trị phần mũ bằng 0 thì người ta lưu trong máy tính các bit là 01111111 tức là +127. Tương tự, ở độ chính xác đơn, giá trị phần mũ là 11111110 (+254) thì giá trị thực phải hiểu là +127 (= 254 – 127). Mỗi định dạng bán chính xác, độ chính xác đơn, độ chính xác kép... đều có một giá trị phân cực riêng của nó...(xem bảng trên). Có hai trường hợp đặc biệt: nếu phần mũ có tất cả các bit bằng 0 thì nó được dùng để biểu diễn các số zero và số không chuẩn hóa, nếu phần mũ có tất cả các bit bằng 1 thì nó được dùng để biểu diễn các vô cực và NaN. Như vậy, giá trị phần mũ của các số chuẩn hóa có tầm nằm trong [-14, 15] ở độ chính xác nữa, [-126, 127] ở độ chính xác đơn, [-1022, 1023] ở độ chính xác kép, hay [-16382, 16383] với độ chính xác bậc bốn. Khi ta nói đến số chuẩn hóa là ta đã loại trừ không xét các số zero, vô cực, NaN và các số không chuẩn hóa.

Cũng cần nhớ rằng, phần định trị trong định dạng nhị phân của IEEE luôn có một bit 1 đầu tiên không được lưu trữ trong máy tính. Nó được gọi là bit "ẩn" hay bit "hiểu ngầm". Chính vì thế, tuy trong máy tính, định dạng độ chính xác đơn có phần định trị gồm 23 bit nhưng ta phải hiểu nó có độ chính xác lên đến 24 bit. Tương tự như vậy, định dạng độ chính xác kép có độ chính xác 53 bit và độ chính xác bậc bốn là 113.
Lấy ví dụ, như ta đã chỉ ra ở phần trên, số π, làm tròn đến độ chính xác 24 bit, có:
* dấu = 0; phần mũ *e* = 1; phần định trị *s* = 110010010000111111011011 (bao gồm cả bit ẩn)
Tổng của giá trị phân cực cho phần mũ (127) và giá trị phần mũ (1) là 128 nên chuỗi 8 bit cần lưu trong máy tính của phần mũ phải là: 10000000
Cuối cùng, toàn bộ giá trị của số π được lưu ở định dạng độ chính xác đơn là
0 10000000 10010010000111111011011 (đã bỏ bit ẩn) = 40490FDB (cơ số 16) 
http://babbage.cs.qc.edu/IEEE-754/32bit.html 

### Các giá trị đặc biệt
#### Số không có dấu

Trong chuẩn IEEE 754, số không có dấu, nghĩa là có đến hai số không: số "không dương" (+0) và số "không âm" (-0). Trong hầu hết các môi trường thực thi, số không dương thường được xuất hiện là "0", trong khi số không âm có thể được in là "-0". Hai giá trị này được xem là bằng nhau về mặt giá trị nhưng một vài phép toán sẽ thông báo kết quả phân biệt giữa +0 và -0. Lấy ví dụ, a/(-0) sẽ cho ra kết quả là vô cực âm còn a/(+0) sẽ cho kết quả là vô cực dương với a là một số dương. Trường hợp a là số âm thì kết quả ngược lại. Tuy nhiên, hai phép toán này khi thông báo kết quả cũng kèm theo thông báo trường hợp ngoại lệ "chia cho số không". Một phép toán arrcot có tính đối xứng dấu chẳng hạn sẽ cho các kết quả khác nhau cho hai trường hợp +0 và -0 mà không có bất kỳ thông báo ngoại lệ nào hết. Sự khác biệt giữa +0 và -0 dễ nhận thấy trong các phép toán phức tạp tại cái gọi là lát cắt rẽ nhánh.

**1. Mô tả chung**

Số thực dấu phẩy động được dùng để biểu diễn các số thực trong tính toán khoa học. 
Tổng quát một số thực X được biểu diễn theo kiểu số dấu phẩy động như sau:
X = M*RE.

Trong đó:

* M là phần định trị (Mantissa)
* R là cơ số (Radix)
* E là phần mũ (Exponent)

**2. Chuẩn IEEE754/85**

* Cơ số R = 2
* Các dạng 32, 44, 64, 80 bit

Ví dụ dạng 32 bit

! 1 bit
! 8 bit
! 23 bit
|-----
| S
| e
| m
|}

* S là bít dấu (số dương S = 0)
* e là mã excess của phần mũ E (e = E+127 hay E = e-127, số 127 ở đây là độ lệch bias)
* m là phần lẽ của phần định trị M (M = 1.m)

Do vậy công thức xác định giá trị số thực như sau:
X = (-1)S * 1.m * 2e-127

**3. Ví dụ số thực dấu phẩy động 32 bit theo chuẩn IEEE754/85**

! 1
! **1**
! **0**
! **0**
! **0**
! **0**
! **0**
! **1**
! **0**
! 1
! 0
! 1
! 0
! 1
! 1
! 0
! 0
! 0
! 0
! 0
! 0
! 0
! 0
! 0
! 0
! 0
! 0
! 0
! 0
! 0
! 0
! 0
|}

* S = 1 -> Số âm (S là 1 bit đầu tiên).
* e = 1000 00102 = 13010 -> E = 130 - 127 = 3 (e là 8 bit tiếp theo).
* m = 101011 -> M = 1.101011 (m là 23 bit còn lại, ở đây không cần quan tâm đến các bit 0 ở cuối vì khi ghép M = 1.m thì các số 0 này không cần viết vào)

X = -1.101011 * 23 = -1101.011 = -13.375 (10 ở hệ nhị phân bằng 2 ở hệ thập phân nên ví dụ **10<sup>3</sup>**2=**2<sup>3</sup>**10)

## Chú thích