01/10/2018, 13:34

Vòng for với số thực

Em có một vi dụ về vòng for:
ví dụ 1:

for(int i = 0.0 ; i != 1.0;i+=0.1)

ví dụ 2

for(int i = 0.0 ; i != 10.0 ; i+=1)

về cơ bản thì em thấy 2 ví dụ này khá giống nhau, ở đây không bản đến các lỗi khác, em chỉ thắc mắc là tại sao ví dụ 1 lại chạy vô hạn vì dĩ nhiên là 1.0 của i khi tăng lên sẽ khác với 1.0 nó so sánh nhưng tại sao ví dụ 2 lại chạy được đúng 10 lần vậy ạ.
Em cám ơn.

*grab popcorn* viết 15:42 ngày 01/10/2018

Đổi 0.1 ra nhị phân (lấy khoảng 64 chữ số). Sau đó lấy 64 chữ số nhị phân đó đổi lại hệ thập phân.
Đổi 1.0 ra hệ nhị phân, sau đó lấy số nhị phân vừa đổi đổi lại ra thập phân.

Làm như trên sẽ thấy được vấn đề.
Đọc thêm: http://www.exploringbinary.com/why-0-point-1-does-not-exist-in-floating-point/

À mà ví dụ trên nên đổi thành double i hoặc float i sẽ đúng với ý của bạn hơn. Vì int i như trên sẽ có cách giải thích khác.

rogp10 viết 15:40 ngày 01/10/2018

23 thôi 64 thì hơi nhiều

Còn 1.0 thì quá đẹp rồi. Số nguyên mà còn nguyên dạng thì tối đa là 2^24 - 1 (do bit 1 đầu mặc nhiên có).

Nobita viết 15:43 ngày 01/10/2018

nếu như em hiểu thì cái vòng for thứ 2 cũng phải chạy vô hạn chứ, sao nó lại chạy đúng 10 lần vậy anh.

Nobita viết 15:45 ngày 01/10/2018

sao lại 24 vậy anh, em chưa hiểu chỗ đấy lắm.

rogp10 viết 15:49 ngày 01/10/2018

Câu trước có liên quan đến câu sau.

*grab popcorn* viết 15:39 ngày 01/10/2018

nè :3
https://www.h-schmidt.net/FloatConverter/IEEE754.html
Vô link trên đổi số 0.1 và coi cái Value actually stored in float
Sau đó đổ 1.0 và cũng coi cái Value actually stored in float

Rồi thử ngẫm xem tại sao nó lại 1 cái vô tận 1 cái ok thử xem.

Nobita viết 15:42 ngày 01/10/2018

nếu float thì là 4 byte => 32 bit, em chưa hiểu tại sao lại giảm 8 bit

Nobita viết 15:36 ngày 01/10/2018

Ok, em cám ơn ạ. Anh có hiểu đươc anh @rogp10 nói đến 24 bit kia là sao không ạ, em chưa tìm được sự liên quan ạ.

*grab popcorn* viết 15:42 ngày 01/10/2018

Ý anh rog10 là cái này nè:
https://en.wikipedia.org/wiki/Single-precision_floating-point_format

Cũng sẽ hơi khó hiểu khi đọc đó

Nobita viết 15:42 ngày 01/10/2018

em cám ơn ạ, cái này em đã được học trong môn tin đại cương, thầy giáo cũng chỉ nêu công thức chứ không có giải thích gì , em cũng chỉ biết khi biểu diễn số thực theo công thức

và được hướng dẫn áp dụng công thức này:


thực sự em chưa hiểu tại sao với 32 bit thì lại là 8 bit e và tương tự với 64 và 80 bit, anh có thể giải thích cho em về điều đó được không ạ, về ý nghĩa của e với m , em cố gắng đọc và gg nhưng em chưa hiểu lắm.

*grab popcorn* viết 15:34 ngày 01/10/2018

Muốn hiểu bạn phải hiểu được Scientific Notation
Thì e là phần lưu trữ exponent và m là phần mantissa.

Ở hệ 10 Scientific Notation của 1 số là m10e
Ở hệ 2 là m
2e

Vd
10 thì Scientific Notation của nó là 1 * 101
2300 = 2.3 * 103
0.1 = 1 * 10-1
0.0345 = 3.45 * 10-2

Thì ở tren là hệ 10. Ở hệ 2 thì sao
Thì cũng tương tự ta có
4 = 1 * 22
5 = 1.25 * 22
0.25 = 1 * 2-2
0.625 = 5/8 = 1.25 * 25* 2-3 = 1.25 * 2-1

Quote trên thì ở hệ 10, 2.3 * 103. 2.3 là phần mantissa và số mũ 3 là phần exponent.
Ở hệ 2 thì lấy vd 1.25 * 22. Ta sẽ có 1.25 lưu ở mantissa (chữ m đó) và số 2 mũ lưu ở exponent (chữ e).
Vì sao phải biểu diễn bằng Scientific Notation? Vì như vậy sẽ có kết quả lớn hơn với lượng bit tương đương.
Như nếu dùng 32 bit thuần, ta chỉ biểu diễn được 2^32 giá trị ~ 4 tỷ. Nhưng với Scientific Notation thì sẽ biểu diễn được
1*(1.999999999)*(2127) ~ 3.40282367* 1038
(tối đa của mantissa là 1.999999999 ~ 2, và tối đa của e là 254 , nếu e = 256 thì số đó biểu diễn là NaN (Not a Number) or Inf nếu m = 0)

Còn vì sao chọn exponent là 8 bit thì cái này mình chờ ng khác giải đáp giúp vậy. Vì mình cũng không rõ tại sao :v

rogp10 viết 15:46 ngày 01/10/2018

Nhưng với Scientific Notation thì sẽ biểu diễn được

Không hẳn, đó chỉ là khoảng giữa số lớn nhất và 0 mà thôi. Còn số số biểu diễn được sẽ nhỏ hơn 2^32 số.

To gain a large dynamic range, floating-point numbers maintain a fixed number of precision bits (also called the significand) and an exponent, which limit the number of significant digits they can represent.

Dễ thấy float có 1 bit dấu + 7 bit mũ = 8 bit vừa đúng 1 byte quá đẹp (double có 23 bit mũ). Ngoài ra có hằng số Avogadro ~ 6.0210^23 và hằng số Planck ~ 6.62610^(-34) Js. Vì vậy 7 bit cho số mũ là tối thiểu.

Nobita viết 15:37 ngày 01/10/2018

mantissa

em cám ơn anh. em tưởng e tối đa là 255 chứ ạ.

Nobita viết 15:49 ngày 01/10/2018

em cám ơn anh, mắc dù vẫn còn nhiều thứ khó hiểu

*grab popcorn* viết 15:48 ngày 01/10/2018

Đúng là 255, xin lỗi mình hơi ẩu.

Bài liên quan
0