гарантировано ли присвоение двух двойных одинаковых битовых комбинаций?

Build> Clean Project

Это сработало для меня. Имел ту же проблему несколько раз, и это, похоже, правильно. Если вы не изменили что-то или не назовете переменную R. Эта проблема обычно происходит из ниоткуда, когда это происходит со мной, поэтому я представляю, что его просто студии Android волнуются. haha

Имейте хороший, и удачи с вашими проектами.

5
задан Stack Danny 17 April 2019 в 12:31
поделиться

1 ответ

Стандарт C ++ четко определяет в [basic.types] # 3 :

Для любого тривиально копируемого типа T, если два указателя на T указывают на отдельные T объекты obj1 и obj2, где ни obj1, ни obj2 не являются потенциально перекрывающимися подобъектами, если нижележащие байты ([intro.memory]), составляющие obj1, копируются в obj2 ], obj2 впоследствии будет иметь то же значение, что и obj1.

Это дает следующий пример:

T* t1p;
T* t2p;
// provided that t2p points to an initialized object ...
std::memcpy(t1p, t2p, sizeof(T));
// at this point, every subobject of trivially copyable type in *t1p contains
// the same value as the corresponding subobject in *t2p

Остается вопрос, что такое value. Мы находим в [basic.fundamental] # 12 (выделено мной):

Есть три типа с плавающей точкой: float, double и long double , Тип double обеспечивает, по крайней мере, такую ​​же точность, как float, а тип long double обеспечивает, по крайней мере, такую ​​же точность, как double. Набор значений типа float является подмножеством набора значений типа double; набор значений типа double является подмножеством набора значений типа long double. Представление значений типов с плавающей запятой определяется реализацией.

Поскольку стандарт C ++ не предъявляет дополнительных требований к представлению значений с плавающей запятой, это все, что вы найдете в качестве гарантии из стандарта, поскольку присваивание требуется только для сохранения значений ( [expr.ass] # 2 ):

В простом назначении (=) объект, на который ссылается левый операнд, изменяется путем замены его значения на результат правого операнда.

Как вы правильно заметили, IEEE-754 требует, чтобы значения, отличные от NaN, сравнивались одинаково, если и только если они имеют одинаковую битовую комбинацию. Поэтому , если ваш компилятор использует IEEE-754-совместимые числа с плавающей запятой, вы должны обнаружить, что присвоение не-NaN чисел с плавающей запятой сохраняет битовые комбинации.


И действительно, ваш код

double a = 5.4;
double b = a;

никогда не должен позволять (a == b) возвращать false. Но как только вы замените 5.4 более сложным выражением, большая часть этой тонкости исчезнет. Это не точный предмет статьи, но в https://randomascii.wordpress.com/2013/07/16/floating-point-determinism/ упоминается несколько возможных способов, которыми невинно выглядящий код может привести к различным результаты (что нарушает утверждения «идентичны битовой структуре»). В частности, вы можете сравнивать 80-битный промежуточный результат с 64-битным округленным результатом, что может привести к неравенству.

0
ответ дан Max Langhof 17 April 2019 в 12:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: