Chuyển đổi int thành float C++

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

giá trị____74
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 IEEE

Biể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 dấu
    unsigned s = i>>31;
    7 với 1 bit
  • Magnificand
    unsigned s = i>>31;
    8 với 23 bit
  • Số mũ
    unsigned s = i>>31;
    9 với 8 bit

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 động

Ví 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 động

Bâ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ố 8

Vớ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.