Почему утверждение "f == (float) (double) f;"неправильно? - PullRequest
8 голосов
/ 28 марта 2019

Я недавно прочитал лекцию по системному программированию, и мой профессор сказал мне, что f == (float)(double) f - это то, что я не могу получить.

Я знаю, что тип double теряет свои данные при преобразовании в float, но я считаю, что потеря происходит только в том случае, если сохраненное число в типе double не может быть выражено в типе float.

Разве это не должно быть так же, как x == (int)(double)x; верно?

картина - это то, как я ее понимаю

enter image description here


Мне очень жаль, что я не четко сформулировал свой вопрос.

Вопрос не в декларации, а в двойном преобразовании типов.Я надеюсь, что вы не потеряете свое драгоценное время по моей вине.

Ответы [ 3 ]

11 голосов
/ 28 марта 2019

Если предположить IEC 60559 , результат f == (float)(double) f зависит от типа f.

Далее, если f - это float, то в этом нет ничего "неправильного""насчет выражения - оно будет оцениваться до true (если f не удерживается NaN, в этом случае выражение будет оцениваться до false).

С другой стороныстороны, x == (int)(double)x (при условии x является int) (потенциально) проблематично, поскольку значение с плавающей запятой МЭК 60559 двойной точности имеет только 53 бита для значащих и 1 , которые не могут представлять всевозможные значения int, если он использует более 53 бит для значения на вашей платформе (по общему признанию, редко).Таким образом, он будет иметь значение true на платформах, где int s 32-битные (для значения используется 31 бит), и может оцениваться до false на платформах, где int s 64-битные (с использованием 63 бит)для значения) (в зависимости от значения).

Соответствующие кавычки из стандарта C (6.3.1.4 и 6.3.1.5):

При преобразовании значения целочисленного типав реальный плавающий тип, если преобразуемое значение может быть точно представлено в новом типе, оно не изменяется.

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

Когда значение действительного плавающего типа преобразуется в действительноеплавающий тип, если преобразуемое значение может быть точно представлено в новом типе, оно остается неизменным.


1 МЭК двойной точностиЗначение 60559 с плавающей запятой состоит из 1 бита для знака, 11 битов для показателя степени и 53 битов для значимого (из которых 1 подразумевается и не сохраняется) - всего 64 (сохраненных) бита.

1 голос
/ 28 марта 2019

В буквальном смысле слова, поставленные в названии,

Почему утверждение «f == (float) (double) f;» неверно?

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

1;

или, если хотите, на утверждение (из оригинального вопроса)

x == (int)(double)x;

(который имеет точно такой же эффект, что и в заголовке, независимо от доступной точности типов int, float и double, т. Е. Вообще ничего).

Программирование, в некоторой степени заботящееся о точности, возможно, следует обратить внимание на разницу между оператором и выражением . выражение имеет значение, которое может быть истинным, ложным или чем-то еще, но когда вы добавляете точку с запятой (как вы делали в вопросе), оно становится оператором (как вы его назвали) в вопросе) и при отсутствии побочных эффектов компилятор может свободно его выбросить.

0 голосов
/ 29 марта 2019

NaN s сохраняются через float => double => float, но они не равны себе.

#include <math.h>
#include <stdio.h>

int main(void) {
    float f = HUGE_VALF;
    printf("%d\n", f == (float)(double) f);
    f = NAN;
    printf("%d\n", f == (float)(double) f);
    printf("%d\n", f == f);
}

Печать

1
0 
0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...