Trong bài đăng này, chúng ta sẽ xem cách thao tác một giá trị số nguyên để có được biểu diễn bit dấu phẩy động có độ chính xác đơn của nó. Cụ thể, chúng tôi sẽ chuyển đổi kiểu dữ liệu unsigned s = i>>31;4 thành kiểu dữ liệu unsigned s = i>>31;0 trong C giả sử kích thước từ là 32 bit. Một ví dụ có thể được nhìn thấy dưới đây
unsigned s = i>>31;0123450x000030390x4640e400 Hầu hết công việc sẽ được thực hiện bằng cách sử dụng các phép toán cấp độ bit, phép cộng và phép trừ. Tuy nhiên, chúng tôi sẽ tự giúp mình với chức năng unsigned s = i>>31;3 tại một thời điểm Theo cách tiếp cận đầu tiên, "bộ chuyển đổi" này sẽ không xử lý các hiệu ứng làm tròn. Điều này có nghĩa là nó sẽ mang lại kết quả tương tự như truyền unsigned s = i>>31;4 đến unsigned s = i>>31;0 chỉ trong phạm vi -10M đến +10M. Các giá trị lớn hơn cần được làm tròn do độ chính xác hạn chế của dấu phẩy động. Bộ chuyển đổi này sẽ không xử lý những trường hợp đó. Đối với một trình chuyển đổi cũng xử lý các hiệu ứng làm tròn, hãy xem bài đăng này Điểm nổi độ chính xác đơn của IEEEBiểu diễn dấu phẩy động xấp xỉ một giá trị thực unsigned s = i>>31;6 như Mỗi biến này được mã hóa bằng một trường bit. Đối với dấu phẩy động có độ chính xác đơn (32 bit), chúng ta có
Trường ký hiệu chỉ được mã hóa thành unsigned E = (int) (log(i<0 ? -i : i)/log(2)); unsigned exp = E + 127;0 đối với giá trị dương và unsigned E = (int) (log(i<0 ? -i : i)/log(2)); unsigned exp = E + 127;1 đối với giá trị âm Magnificand unsigned s = i>>31;8 là một phân số nhị phân ở dạng Trong đó mỗi unsigned s = i>>31;6 là một chữ số nhị phân, unsigned E = (int) (log(i<0 ? -i : i)/log(2)); unsigned exp = E + 127;0 hoặc unsigned E = (int) (log(i<0 ? -i : i)/log(2)); unsigned exp = E + 127;1. Đối với các số nguyên như số nguyên, phạm vi của các giá trị dấu phẩy động được cho là chuẩn hóa. Trong trường hợp này, chúng tôi chỉ mã hóa các bit theo sau điểm nhị phân (ngụ ý là số 1 đứng đầu). Độ chính xác của phần phân số unsigned E = (int) (log(i<0 ? -i : i)/log(2)); unsigned exp = E + 127;6 được giới hạn ở 23 bit. Đây được gọi là trường unsigned E = (int) (log(i<0 ? -i : i)/log(2)); unsigned exp = E + 127;7 Cuối cùng, chúng ta có trường số mũ. Giá trị của unsigned s = i>>31;9 được liên kết với 8 bit được sử dụng để mã hóa nó như sau Trong đó unsigned E = (int) (log(i<0 ? -i : i)/log(2)); unsigned exp = E + 127;9 là giá trị 8 bit không dấu (phạm vi 0-255) và Bias = 127. Phạm vi có thể có của các giá trị unsigned s = i>>31;9 là từ -126 đến 127 (trường số mũ không thể là tất cả các số 0 hoặc tất cả các số cho các giá trị chuẩn hóa) Ba trường này cùng nhau tạo thành biểu diễn bit dấu phẩy động có độ chính xác đơn 32 bit của một số như sau Với unsigned s = i>>31;7 là 1 bit, unsigned E = (int) (log(i<0 ? -i : i)/log(2)); unsigned exp = E + 127;9 dài 8 bit và unsigned E = (int) (log(i<0 ? -i : i)/log(2)); unsigned exp = E + 127;7 dài 23 bit Ví dụ mã hóa dấu phẩy độngVí dụ, hãy xem cách mã hóa số unsigned s = i>>31;24 trong biểu diễn dấu phẩy động Vì nó là một giá trị dương, chúng ta sẽ có unsigned s = i>>31;25 Để giải mã các giá trị của unsigned s = i>>31;8 và unsigned s = i>>31;9, chúng tôi sẽ chuyển đổi unsigned s = i>>31;24 thành giá trị nhị phân Bây giờ, chúng tôi sẽ biểu thị giá trị nhị phân này ở dạng unsigned s = i>>31;29 Chúng tôi nhận được unsigned s = i>>31;80 có nghĩa là unsigned s = i>>31;81. Giá trị 141 (ở dạng thập phân) cần được mã hóa dưới dạng số 8 bit không dấu. unsigned s = i>>31;82 Chúng tôi cũng nhận được unsigned s = i>>31;83. Các chữ số sau điểm nhị phân là unsigned s = i>>31;84. Chúng được mã hóa trong trường unsigned E = (int) (log(i<0 ? -i : i)/log(2)); unsigned exp = E + 127;7. Chúng tôi đệm sang bên phải bằng số không (chúng không thay đổi giá trị phân số nhị phân) để nhận 23 bit Cuối cùng, chúng ta sẽ nhận được mã hóa 32 bit sau đây cho số unsigned s = i>>31;24 dưới dạng dấu phẩy động có độ chính xác đơn Bộ chuyển đổi số nguyên sang dấu phẩy độngBây giờ, chúng ta sẽ xem cách lập trình bộ chuyển đổi trong C. Các bước mà chúng tôi sẽ làm theo khá giống với các bước trong ví dụ trên. Chúng tôi sẽ giả định rằng unsigned s = i>>31;4 mã hóa một số đã ký trong biểu diễn bù hai bằng cách sử dụng 32 bit Chúng tôi sẽ tái tạo biểu diễn bit dấu phẩy động bằng cách sử dụng kiểu dữ liệu ____288. Chúng tôi sẽ gọi loại dữ liệu này là unsigned s = i>>31;89 unsigned s = i>>31;7 Đầu tiên, chúng ta sẽ xác định bit dấu unsigned s = i>>31;7. Giá trị chúng tôi đang chuyển đổi thành float là unsigned s = i>>31;91 unsigned s = i>>31; Để có được unsigned s = i>>31;7, chúng tôi chỉ chuyển sang bit ngoài cùng bên trái của số nguyên 32 bit. Trong biểu diễn phần bù của hai, giá trị này là unsigned E = (int) (log(i<0 ? -i : i)/log(2)); unsigned exp = E + 127;1 đối với giá trị âm và unsigned E = (int) (log(i<0 ? -i : i)/log(2)); unsigned exp = E + 127;0 đối với giá trị dương, giống như đối với số float Tiếp theo, chúng ta sẽ lấy số mũ ________số 8Với dòng đầu tiên, ta có lũy thừa cao nhất của hai unsigned s = i>>31;9 sao cho unsigned s = i>>31;96. Chúng tôi làm điều đó với toán tử logarit cơ số 2 Với dòng thứ hai, chúng tôi tính đến Bias = 127 để nhận được unsigned E = (int) (log(i<0 ? -i : i)/log(2)); unsigned exp = E + 127;9 Cuối cùng, chúng tôi sẽ tính toán trường unsigned E = (int) (log(i<0 ? -i : i)/log(2)); unsigned exp = E + 127;7. Chúng tôi bắt đầu bằng cách tính toán unsigned s = i>>31;8. Chúng ta có thể bỏ dấu âm và chỉ xử lý giá trị tuyệt đối của unsigned s = i>>31;00 vì dấu đã được mã hóa bởi unsigned s = i>>31;7 unsigned s = i>>31;2 Trường ________ 87 thu được bằng cách bỏ 1 giá trị quan trọng nhất unsigned s = i>>31;8 Tại thời điểm này, unsigned E = (int) (log(i<0 ? -i : i)/log(2)); unsigned exp = E + 127;7 chứa tất cả các bit sau bit đầu tiên Tiếp theo, chúng tôi đẩy phần đầu của trường unsigned E = (int) (log(i<0 ? -i : i)/log(2)); unsigned exp = E + 127;7 lên vị trí bit thứ 23 unsigned s = i>>31;9 Trường unsigned E = (int) (log(i<0 ? -i : i)/log(2)); unsigned exp = E + 127;7 dài 23 bit. Số mũ unsigned s = i>>31;9 cho biết có bao nhiêu địa điểm trong số này đã được sử dụng. Chúng tôi chỉ cắt bớt 23 bit quan trọng nhất nếu trường quá dài hoặc đệm có số 0 ở bên phải nếu trường quá ngắn Thấy rằng những gì chúng tôi làm cho số lượng lớn là cắt bớt. Điều này tương đương với việc làm tròn về 0. Hành vi C mặc định là làm tròn đến chẵn (nó sẽ làm tròn đến giá trị gần nhất). Vì lý do này, kết quả của trình chuyển đổi của chúng tôi sẽ khác với kết quả truyền của C đối với các giá trị lớn (những giá trị có hơn 24 bit có nghĩa) Cuối cùng, chúng tôi chứa tất cả các lĩnh vực với nhau unsigned s = i>>31;0 Đặt tất cả lại với nhau trong hàm unsigned s = i>>31;07, chúng ta sẽ nhận được unsigned s = i>>31;2 Chúng tôi đã bao gồm một mệnh đề đặc biệt cho unsigned s = i>>31;08 không phải là giá trị chuẩn hóa thử nghiệmĐể kiểm tra tính hợp lệ của trình chuyển đổi của chúng tôi, chúng tôi sẽ so sánh kết quả của hàm unsigned s = i>>31;07 với thao tác truyền unsigned s = i>>31;20 unsigned s = i>>31;6 Tóm lại, kiểu dữ liệu unsigned s = i>>31;89 chỉ là kiểu dữ liệu unsigned s = i>>31;22. Để làm cho C nhận ra các bit đó là một unsigned s = i>>31;0, chúng ta khai báo một con trỏ float unsigned s = i>>31;24 và truyền cho nó địa chỉ của kết quả unsigned s = i>>31;89. unsigned s = i>>31;26. Bằng cách này, các bit tại unsigned s = i>>31;27 sẽ được C công nhận là float Sau khi biên dịch và chạy mã này, chúng tôi sẽ không nhận được kết quả nào. Điều này có nghĩa là các giá trị của bộ chuyển đổi và thao tác truyền đều bằng nhau đối với phạm vi giá trị số nguyên đã kiểm tra. Đối với một trình chuyển đổi xử lý toàn bộ phạm vi giá trị unsigned s = i>>31;4, bạn có thể đăng bài này Chúng ta có thể chuyển đổi int thành float trong C không?Khi bạn đã tạo một biến thuộc loại nhất định, biến đó sẽ bị khóa vĩnh viễn với loại đó. Vì vậy, trong trường hợp của bạn, bạn đã tạo i dưới dạng int. Bạn không thể chỉ định lại i dưới dạng float sau đó . Một int luôn là một int và sẽ vẫn là một int miễn là nó được khai báo là một int và sẽ không bao giờ có thể thay đổi thành bất cứ thứ gì ngoại trừ một int.
Bạn có thể chuyển đổi int sang float không?Chuyển đổi số nguyên thành số float
. By using the float() function, we can convert integers to floats.
Có thể so sánh int và float trong C không?Gán số nguyên cho float và so sánh trong C/C++
. Chúng không thể có số thập phân. Float là kiểu dữ liệu dùng để xác định một số có giá trị phân số . Đây cũng có thể có số thập phân.
Chúng ta có thể chuyển đổi char thành float trong C không?Hàm atof() chuyển đổi một chuỗi ký tự thành giá trị dấu phẩy động có độ chính xác kép . Chuỗi đầu vào là một chuỗi các ký tự có thể được hiểu là một giá trị số của kiểu trả về được chỉ định. |