Та компьютер дээр 0.1 + 0.2 гэж бичээд 0.300000004 гарч ирэхийг харсан уу? Энэ нь таны нүд буруу харж байна гэсэн үг биш, бас компьютерийн алдаа биш. Энэ бол floating point representation-ийн төвөгтэй үзэгдэл юм.
Яагаад 0.1 + 0.2 яг 0.3 болдоггүй вэ?
Компьютер дотор бүх тоо хоёртын систем (binary) дээр хадгалагддаг. Зарим арвантын бутархай тоонуудыг хоёртын системд яг нарийн хөрвүүлэх боломжгүй:
- 0.1 = 0.0001100110011001100110011…₂ (давтагдана)
- 0.2 = 0.0011001100110011001100110…₂ (давтагдана)
Битүүдийг 32-бит эсвэл 64-битэд хязгаарлагдмал хадгалдаг тул нарийвчлалыг бага зэрэг алдаатайгаар хадгална. Ингээд 0.1 + 0.2 бодит утга нь 0.300000004 гэх мэт ойролцоо утгад хүрдэг.
IEEE-754 Floating Point Стандарт
Компьютерийн хувьд floating point тоонуудыг хадгалах стандарт нь IEEE-754 юм. Энэ нь бит бүрийн зохион байгуулалт, нарийвчлалыг тогтоодог.
Single Precision (32-бит)
- Sign (S): 1 бит → эерэг эсвэл сөрөг
- Exponent (E): 8 бит → тоог масштаблахад ашиглагдана
- Mantissa / Fraction (M): 23 бит → нарийвчлалыг хадгална
Томьёо:
(−1)^S × 1.M × 2^(E−127)
Double Precision (64-бит)
- Sign: 1 бит
- Exponent: 11 бит (bias = 1023)
- Mantissa: 52 бит
- Илүү нарийвчлалтай, том утга хадгална
Floating Point Алдаа
Floating point тоо нь ойролцоо утга. Зарим тоо яг нарийн хадгалагддаггүй. IEEE-754 стандарт нь алдаа гарах магадлалыг багасгах, бүх компьютер адилхан тооцоолох боломжийг өгдөг. Програмчлалд floating point тоонуудыг харьцуулахдаа зөв арга хэрэглэвэл алдаа гарах магадлал багасна.
Жишээ: 0.1 + 0.2
32-битээр бодохдоо:
0.1 → 0.10000000149011612 0.2 → 0.20000000298023224 ---------------------------- 0.1 + 0.2 ≈ 0.30000000447034836
Double precision (64-бит) ашиглавал нарийвчлал сайжирна, гэхдээ жижиг алдаа хэвээрээ. Энэ нь IEEE-754 стандартын онцлог бөгөөд бит бүрийн нарийн төлөвлөгөөний үр дүн юм.
Яагаад IEEE-754 хэрэгтэй вэ?
- Компьютер бүх тоог хоёртын систем дээр хадгалдаг.
- Зарим арвантын тоо хоёртын системд яг хөрвөх боломжгүй.
- IEEE-754 нь тоонуудыг тогтвортой, стандарт аргаар хадгалах арга тодорхойлдог. Ингэснээр бүх компьютер нэгэн адил ойлгодог.
Програмчлалд хэрхэн зөв ажиллах вэ?
- Floating point тоонуудыг харьцуулахдаа exact equality ашиглахгүй. Жишээ:
- Decimal нарийвчлалыг шаардсан тохиолдолд
BigDecimal(Java),decimal(Python) зэрэг library ашиглах. - Тооцооллын нарийвчлалыг үргэлж анхаарч, бага зэрэг алдааг зөвшөөрөх.
Эцэст нь хэлэхэд, 0.1 + 0.2 = 0.30000000000000004 гэдэг нь алдаа биш, floating point representation-ийн зөвшөөрөгдсөн ойролцоо утга юм. Энэ үзэгдэл нь бүх компьютерийн арифметикт хэвийн бөгөөд зөв аргаар удирдвал програмчлалд аюулгүй ашиглаж болно.