Arhn - архитектура программирования

x*x != x*x в автопеременной?

Как изменить x * x, сохранив его в «переменной auto»? Я думаю, что он должен оставаться прежним, и мои тесты показывают, что типы, размеры и значения, по-видимому, одинаковы.

Но даже x * x == (xx = x * x) ложно. Что за черт?

(Примечание: я знаю IEEE 754 и то, как работают float и double, и их обычные проблемы, но этот меня сбивает с толку.)

#include <iostream>
#include <cmath>
#include <typeinfo>
#include <iomanip>
using namespace std;

int main() {
    auto x = sqrt(11);
    auto xx = x * x;
    cout << boolalpha << fixed << setprecision(130);
    cout << "   xx == 11           " << (   xx == 11          ) << endl;
    cout << "x * x == 11           " << (x * x == 11          ) << endl;
    cout << "x * x == xx           " << (x * x == xx          ) << endl;
    cout << "x * x == (xx = x * x) " << (x * x == (xx = x * x)) << endl;
    cout << "x * x == x * x        " << (x * x == x * x       ) << endl;
    cout << "types        " << typeid(xx).name() << " " << typeid(x * x).name() << endl;
    cout << "sizeofs      " << sizeof(xx) << " " << sizeof(x * x) << endl;
    cout << "xx           " << xx    << endl;
    cout << "x * x        " << x * x << endl;
}

Вот результат:

   xx == 11           true
x * x == 11           false
x * x == xx           false
x * x == (xx = x * x) false
x * x == x * x        true
types        d d
sizeofs      8 8
xx           11.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
x * x        11.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Скомпилировано с этим:

C:\Stefan\code\leetcode>g++ test4.cpp -static-libstdc++ -std=c++11 -o a.exe

C:\Stefan\code\leetcode>g++ --version
g++ (GCC) 4.8.1
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

  • Это не имеет ничего общего с auto. Все ваши переменные выводятся как doubles, это просто вопрос точности с плавающей запятой. См., например. это. 17.02.2016
  • Не имеет отношения, но вы можете напечатать bools как true или false, используя std::cout<< std::boolalpha;. Это сэкономит вам немного кода. 17.02.2016
  • @juanchopanza Спасибо, использовал это сейчас. 17.02.2016
  • @vsoftco Ваша ссылка, кажется, не объясняет этого. Это действительно так? 17.02.2016
  • @vsoftco Вопрос совершенно другой, и ни один из ответов не объясняет мою проблему. Похоже, вы не поняли моего вопроса. 17.02.2016

Ответы:


1

Это обычная неточность с двойниками. Вы не упоминаете свое оборудование, но на x86 (32-битный Intel) временные файлы, используемые во время вычислений, представляют собой двойные числа длиной 10 байт. x * x будет одним из них, а xx = x * x будет сохранено в 8-байтовом двойнике перед загрузкой обратно в FPU для сравнения.

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

17.02.2016
  • Есть ли способ получить такой 10-байтовый двойник в качестве переменной? 17.02.2016
  • @StefanPochmann Объявите это как long double, но это зависит от того, что поддерживает ваш компилятор. Некоторые будут использовать 10 байтов для long double, другие будут использовать 8. Я не знаком с g++, чтобы сказать, что он делает. 17.02.2016
  • long double сработало, теперь все сравнения показывают то, что я ожидал (а sizeof равно 12). Спасибо! 17.02.2016
  • @StefanPochmann: long double может быть выровнено до 4 байтов по соображениям производительности. 17.02.2016
  • Проверьте свой FLT_EVAL_METHOD 18.02.2016
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..