Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> float или double ? Нужен ли float.. 
:(
    Опции темы
feodorv
Дата 18.7.2013, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(hoz @  17.7.2013,  23:31 Найти цитируемый пост)
У каждого из них будет фиксированная точность и изменяющаяся?

Для каждого числа будет определена абсолютная и относительная точность представления в форме числа с плавающей точкой:
  • Число 1.0; абсолютная погрешность представления - (1 * эпсилон), относительная - эпсилон
  • Число 1.0е-2; абсолютная погрешность представления - (1.0e-2 * эпсилон), относительная - эпсилон
  • Число 1.0е-10; абсолютная погрешность представления - (1.0e-10 * эпсилон), относительная - эпсилон
  • Число 1.0е10; абсолютная погрешность представления - (1.0e10 * эпсилон), относительная - эпсилон
Как видно, абсолютная погрешность представления меняется (в зависимости от представляемого числа), поэтому она "изменяющаяся". И "изменяющаяся" она не для конкретного выбранного числа (в зависимости от фаз Луны, что ли, сегодня одна, завтра - другая))), а меняется вместе с представляемым числом. В то же время относительная погрешность никак не меняется при выборе представляемого числа, поэтому она "фиксированная"...


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Wuffur
Дата 19.7.2013, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 22.7.2007

Репутация: нет
Всего: нет



Давайте ещё про long double похоливарим. smile 
PM MAIL ICQ   Вверх
Alexeis
Дата 19.7.2013, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 4
Всего: 459



  Да, был неправ на счет тригонометрических функций. Для AMD64/x86 процов нет специальной реализации sinf/atanf . Сопроцессор считает их исключительно как double . У него просто нет аппаратных вычислительных блоков разрядности 32. Для тригонометрии получается double будет работать быстрее за исключением случаев не хватки кэша процессора.
  Но я вот провел другой эксперимент не зависящий от кэша проца. Для складирования использовал массивы небольшой размерности (на 100 элементов), так чтобы double и float были в равных условиях. Кроме того, чтобы компилятор не филонил, зарядил даже вывод результатов на экран.

Вот такой получился код
Код

    SetThreadAffinityMask(GetCurrentThread(), 1);
    LARGE_INTEGER l11, l12;
    LARGE_INTEGER l21, l22;
    float fres[100];
    float dres[100];
    int r = _set_SSE2_enable(1);
    _control87(_PC_24, _MCW_PC); 
    QueryPerformanceCounter(&l11);
    for (float i = 0.0f; i < 1000000.0f; i += 1.0f)
    {
        fres[int(i / 10000.0f)] += (i + 50.0f) / (i * i) - 
                                    456.0f / (i + 17.2f) + 
                                    (i + 2.0f*i*i + 0.01f * i*i*i) / (i*i*0.7f - 0.125f*i);
    }
    QueryPerformanceCounter(&l12);
    int count1 = (l12.QuadPart - l11.QuadPart);
    _control87(_PC_64, _MCW_PC); 
    QueryPerformanceCounter(&l21);
    for (double i = 0.0; i < 1000000.0; i += 1.0)
        dres[int(i / 10000.0)] += (i + 50.0) / (i * i) - 
                                  456.0 / (i + 17.2) + 
                                  (i + 2.0*i*i + 0.01 * i*i*i) / (i*i*0.7 - 0.125*i);    
    QueryPerformanceCounter(&l22);
    int count2 = (l22.QuadPart - l21.QuadPart);

    std::cout << count1 << " " << count2;
    std::string s;
    std::cin >> s;

    for (int i = 0; i < 100; i++)
    {
        std::cout << fres[i];
        std::cout << dres[i];
    }
    return 0;

  
Результат для float -в получился в 2 раза быстрее. Причем SSE2 мало влияет на результат, поскольку такой код не очень хорошо оптимизируется. Зато разница по скорости тем заметнее чем сложнее выражение. По-моему это явно указывает на то, что сопроцессору не все равно с одинарной или двойной точностью считать. 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
feodorv
Дата 19.7.2013, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Alexeis,  smile 

Только у Вас там стоит _PC_64, что на мой взгляд означает long double, а не просто double.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Alexeis
Дата 19.7.2013, 17:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 4
Всего: 459



Мантиса у дабла 53 бита? Нужно попробовать с _PC_53 тогда.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
volatile
Дата 19.7.2013, 18:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



Цитата(Alexeis @  19.7.2013,  13:49 Найти цитируемый пост)
сопроцессору не все равно с одинарной или двойной точностью считать.  

Вероятно да, это так.

Но сам по себе выбор типа: float или double - никакой роли на точность сопроцессора, а следовательно на скорость, не оказывают.
Например, если перед дабл-вычислением поставить _control87(_PC_24, _MCW_PC);
то будет считать с такой - же скоростью как и float. (и вероятно, с такой-же реальной точностью.)

В общем здесь весь фокус в инструкции _control87 ();
Но это же чисто мелко-мягкая фича, как я понимаю?


PM MAIL   Вверх
Alexeis
Дата 19.7.2013, 21:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 4
Всего: 459



Цитата(volatile @  19.7.2013,  19:07 Найти цитируемый пост)
Например, если перед дабл-вычислением поставить _control87(_PC_24, _MCW_PC);
то будет считать с такой - же скоростью как и float. (и вероятно, с такой-же реальной точностью.)

  Да, имеется такая пакость, когда имеешь на руках "половинные" даблы. Реально считается только половина цифр. И занимают кучу памяти и нифига не точные. 

Цитата(volatile @  19.7.2013,  19:07 Найти цитируемый пост)
Но это же чисто мелко-мягкая фича, как я понимаю?

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


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
volatile
Дата 20.7.2013, 11:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



Цитата(Alexeis @  19.7.2013,  21:29 Найти цитируемый пост)
Мне кажется только аппаратно можно повлиять.  

Ну вот в связи с этим, на вопрос новичка "зачем нужен float?" 
отвечать - для увеличения скорости, всеже не совсем верно.
скорость увеличиваецца не от float, а от какиx-то аппартных (плохо/не переносимых) штучек.
О которых новичку вовсе пока не нужно знать.
Да и НЕ новичку кстати тоже (помним о "premature optimization"), только если уж совсем подопрет...

Правильным-же ответом на вопрос "зачем нужен float?" все-же будет - экономия памяти. 
нет?

PM MAIL   Вверх
Alexeis
Дата 20.7.2013, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 4
Всего: 459



volatile, ну если С++ это только AMD64 и x86 то да. Есть много железяк где нет 64х битного сопроцессора, на некоторых совсем нет никакого даже 32х битного и float-ы вычисляются программно через библиотеки идущие в комплекте с компилятором. В общем случае, float должен быть не медленнее double, a double не медленнее long double. Если пишется универсальный программный модуль, то это следует учитывать. 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
hoz
  Дата 21.7.2013, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 27.6.2013

Репутация: нет
Всего: нет



Мда. Вроде как уже не первый день программирую. По крайне мере, кой-чиво уже писал. А вот эти основы для меня самые трудные для понимания. Уже казалось бы, и так и сяк кручу и верчу. Но как-то не всё улаживается в голове.
Взять хотя бы понятия абсолютная погрешность и относительная погрешность. О погрешностях я прочитал тут тут
Вот как у чисел с фиксированной точностью может быть так:
Цитата

Для чисел с фиксированной точкой
постоянная абсолютная погрешность
переменная относительная погрешность

А у чисел с плавающей точкой (запятой) иначе:
Цитата

Для чисел с плавающей запятой
переменная абсолютная погрешность
постоянная относительная погрешность

Понять не выходить. Относительно чего всё это анализировать?

Думаю, если оно не пригодится дальше, может вообще пропустить  smile  smile 
Хотя хочется уже добить этот момент и дальше свободно всё штудировать.
PM MAIL   Вверх
feodorv
Дата 21.7.2013, 15:38 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(hoz @  21.7.2013,  15:41 Найти цитируемый пост)
Думаю, если оно не пригодится дальше, может вообще пропустить

Я бы забил)))

Цитата(hoz @  21.7.2013,  15:41 Найти цитируемый пост)
Хотя хочется уже добить этот момент и дальше свободно всё штудировать. 

Ну, если охота пуще неволи...

Что именно в этом абзаце не понятно:

Для каждого числа будет определена абсолютная и относительная точность представления в форме числа с плавающей точкой:
  • Число 1.0; абсолютная погрешность представления - (1 * эпсилон), относительная - эпсилон
  • Число 1.0е-2; абсолютная погрешность представления - (1.0e-2 * эпсилон), относительная - эпсилон
  • Число 1.0е-10; абсолютная погрешность представления - (1.0e-10 * эпсилон), относительная - эпсилон
  • Число 1.0е10; абсолютная погрешность представления - (1.0e10 * эпсилон), относительная - эпсилон

Как видно, абсолютная погрешность представления меняется (в зависимости от представляемого числа), поэтому она "изменяющаяся". И "изменяющаяся" она не для конкретного выбранного числа (в зависимости от фаз Луны, что ли, сегодня одна, завтра - другая))), а меняется вместе с представляемым числом. В то же время относительная погрешность никак не меняется при выборе представляемого числа, поэтому она "фиксированная"...


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
hoz
Дата 21.7.2013, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 139
Регистрация: 27.6.2013

Репутация: нет
Всего: нет



Цитата(feodorv @  21.7.2013,  15:38 Найти цитируемый пост)
Число 1.0е-2; абсолютная погрешность представления - (1.0e-2 * эпсилон), относительная - эпсилон

Тут же e и есть эпсилон. Откуда там после 1.0е-2 будет ещё * эпсилон?
p.s. Видать скоро точно сдамся  smile 
PM MAIL   Вверх
Wuffur
Дата 21.7.2013, 16:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 22.7.2007

Репутация: нет
Всего: нет



Цитата(hoz @ 21.7.2013,  16:03)
Цитата(feodorv @  21.7.2013,  15:38 Найти цитируемый пост)
Число 1.0е-2; абсолютная погрешность представления - (1.0e-2 * эпсилон), относительная - эпсилон

Тут же e и есть эпсилон. Откуда там после 1.0е-2 будет ещё * эпсилон?
p.s. Видать скоро точно сдамся  smile


О господи, e-2 - это порядок в десятичном представлении. 1.0 - мантисса в десятичном представлении. Разница между, к примеру float2, который 2^-8(если первая не значащая) последним битом и следующим в памяти за ним числом(предпоследний бит представлен для +inf,-inf и различных NaN, подробнее в википедии) и есть машинное эпсилон. Только сначала нужно перегнать всё в двоичное представление, а это сделано для простоты восприятия программистом.  smile 


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

Это сообщение отредактировал(а) Wuffur - 21.7.2013, 16:45
PM MAIL ICQ   Вверх
feodorv
Дата 21.7.2013, 17:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(hoz @  21.7.2013,  17:03 Найти цитируемый пост)
Тут же e и есть эпсилон. Откуда там после 1.0е-2 будет ещё * эпсилон?

Ээээ, нет. Постойте. 

Буковка e в записи числа указывает, что дальше пойдёт целое число, означающее прядок числа:
Цитата

одна сотая: 1.0e-2
две десятых: 2.0e-1
тысяча: 1.0e3
миллион: 1.0e6
тысяча миллионов: 1000.0e6
миллион тысяч: 1000000.0e3


Эти примеры понятны? (.0 в записи числа с плавающей точкой - необязательны, но приведены для порядка).


Что же такое эпсилон?
Цитата(feodorv @  18.7.2013,  09:30 Найти цитируемый пост)
см. по ссылке Wuffur

Находим ссылку, которую дал Wuffur: Для самообразования: http://en.wikipedia.org/wiki/Machine_epsilon
Заходим по ней, видим название статьи: Machine epsilon. Так вот он, какой эпсилон - машинный!
Для float это значение равно 2 ^ -24 = 5.96e-08. 


Что это значит?
Цитата(feodorv @  18.7.2013,  09:30 Найти цитируемый пост)
Конкретное число x в машинном представлении (в силу ограниченности возможностей представления различных чисел на ЭВМ) может являться совсем другим числом X (округлённым до ближайшего "машинного" числа). Поэтому возникает погрешность машинного представления: вместо x имеем X. 

То есть для разницы машинного представления и первоначального числа: |X - x| < (X * 5.96e-08) или двойное неравенство X - (X * 5.96e-08) < x < X + (X * 5.96e-08)


А с чего вдруг моё хорошее число x может превратиться в какое-то машинное X?
И вот тут хочешь-не хочешь, а придётся разбираться с форматом представления чисел с плавающей точкой (ссылка от bsaЧисло одинарной точности)
Внезапно выяснится, что и мантисса, и порядок находятся в двоичной системе счисления (а не в десятеричной!), что лидирующая единица не участвует в представлении числа, но держится в уме и т.д. и т.п.

И вот с этого последнего и стОит начинать разговор. Всё остальное - лирика...

Добавлено через 5 минут и 4 секунды
Ух ты, пока писАл, Wuffur, уже ответил)))


Цитата(Wuffur @  21.7.2013,  17:29 Найти цитируемый пост)
Feodorv, и ни надо новичкам в десятичном представлении числа с плавающей точкой показывать, пусть учатся, а то будет у них глупое представление, которое потом из них не выбьешь. 

Я жеж только за!


Цитата(Wuffur @  21.7.2013,  17:29 Найти цитируемый пост)
К тому же сам немного ошибаешься.

Я и за полную и неприкрытую правду))) Где, в чём?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Wuffur
Дата 21.7.2013, 17:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 22.7.2007

Репутация: нет
Всего: нет



Цитата(feodorv @ 21.7.2013,  17:20)
Цитата(Wuffur @  21.7.2013,  17:29 Найти цитируемый пост)
К тому же сам немного ошибаешься.

Я и за полную и неприкрытую правду))) Где, в чём?

В том что если умножить 10^n это то же самое что 2^m, которое и указывает порядок. С помощью 1.0e-2 указывает, что на экран вывелось именно 10^-2, а не 2^-8. Мантисса (1),0100011, для float32. И машинное эпсилон надо умножать на 2^-8.

Это сообщение отредактировал(а) Wuffur - 21.7.2013, 17:57
PM MAIL ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0984 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.