2012-11-16 2 views
2
float b = 1.0f; 
int i = b; 
int& j = (int&)i; 
cout<<j<<endl; 

о/р = 1Confused на выходе следующей программы

Но для следующего сценария

float b = 1.0f; 
int i = b; 
int& j = (int&)b; 
cout<<j<<endl; 

O/P = 1065353216

, так как с той же значение должно показать тот же результат ... Может кто-нибудь, пожалуйста, дайте мне знать, что происходит на самом деле, когда я делаю некоторые изменения в строке №3?

ответ

1

Целое число 1 и с плавающей запятой 1.0f может быть математически одним и тем же значением, но в C++ у них разные типы, с разными представлениями.

литье lvalue к ссылке равно reinterpret_cast; он говорит: «Посмотрите, что находится в этой ячейке памяти, и интерпретируйте эти байты как int».

В первом случае память содержит int, поэтому интерпретация этих байтов как int дает ожидаемое значение.

Во втором случае, память содержит float, так что вы видите байты (или, возможно, только некоторые из них, или, возможно, дополнительных отражателей тоже, если sizeof(int) != sizeof(float)), которые представляют собой число с плавающей точкой, переосмысленное как целое ,

Ваш компьютер, вероятно, использует 32-разрядные int и 32-разрядные IEEEfloat изображений. Значение float1.0f имеет знаковый бит нуля, показатель нуля (представленный 8-битовым значением 127 или 01111111 в двоичном формате), а мантисса 1 (представлена ​​23-битовым значением 0), поэтому 32 -битовый модель будет выглядеть следующим образом:

00111111 10000000 00000000 00000000 

Когда переосмыслено как целое, это дает шестнадцатеричное значение 0x3f800000, которое в десятичной системе счисления 1065353216.

+0

Можете ли вы, пожалуйста, объяснить некоторые вещи в отношении вашего абзаца lasr. Я не знаю гораздо больше об этом материале мантиссы. Я новичок в C++. – Kenta

+0

@vivek: Следуйте по [link] (http://en.wikipedia.org/wiki/IEEE_floating_point) статье Википедии о представлениях с плавающей запятой IEEE, которая объясняет их лучше, чем я могу. –

+0

Thankx Mike Seymou .. – Kenta

2

В первом случае вы правильно инициализируете j, а литье является излишним. Во втором случае вы делаете это неправильно (т. Е. К объекту другого типа), но литье отключает компилятор.

В этом втором случае то, что вы получаете, возможно, является внутренним представлением 1.0, интерпретируемым как целое.

0

Первый из них первым отправляет b в int, прежде чем назначить его i. Это «правильный» способ, так как компилятор будет правильно преобразовывать значение.

Второй не выполняет никаких отливок и переписывает b в качестве целого числа. Если вы читаете floating point format, вы можете точно узнать, почему вы получаете то значение, которое получаете.

Под обложками все ваши переменные являются всего лишь наборами бит. Как вы интерпретируете эти биты, изменяется воспринимаемое значение, которое они представляют. В первом вы перестраиваете битовый шаблон, чтобы сохранить «воспринимаемое» значение (1). Во втором случае вы не перестраиваете битовый шаблон, и поэтому воспринимаемое значение неправильно преобразуется.

3

В первом, вы делаете все хорошо. Компилятор способен преобразовывать float b в int i, теряя точность, но это нормально. Теперь посмотрим на мое окно отладчика во время выполнения вашего второго примера:

enter image description here

К сожалению для моего российского IDE интерфейс, первый столбец имя переменной, второе значение, а третий тип ,

Как вы можете видеть, теперь поплавок просто интерпретируется как int. Таким образом, ведущие 1 биты интерпретируются как биты целого, что приводит к результату, который вы получаете. Таким образом, вы берете двоичное представление float (обычно оно представлено как знаковый бит, мантисса и экспонента) и пытаетесь интерпретировать его как int.

1

Ссылка не выполняет распределение памяти, она просто помещает запись в таблицу локальных имен и их адресов. В первом случае имя «j» указывает на память, ранее выделенную для типа int (для переменной «i»), тогда как во втором случае имя «j» указывает на память, выделенную для типа данных float (для переменной «b»). Когда вы используете компилятор «j», интерпретирует данные по соответствующему адресу так, как если бы он был int, но на самом деле там размещен некоторый «float», поэтому вы получаете некоторые «странные» цифры вместо 1

Смежные вопросы