Выбор нужной точности. (float/double)

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

versus
Сообщения: 45
Зарегистрирован: 12 май 2004, 01:37

Читал как-то у Страуструпа
Типы с плавающей точкой.

...

Выбор нужной точности в реальных задачах требует хорошего понимания природы машинных вычислений с плавающей точкой. Если у вас его нет, либо проконсультируйтесь с кем-нибудь, либо изучите проблему сами, либо используйте double и надейтесь на лучшее.
А в чем собственно проблема-то?
Defder
Сообщения: 64
Зарегистрирован: 24 май 2005, 12:25

Производительность операций с float выше, чем с double
Eugie
Сообщения: 708
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

Производительность операций с float выше, чем с double
Я бы сказал - с точностью до наоборот :)
PS. Внутренее представление в сопроцессоре как раз double
Аватара пользователя
AiK
Сообщения: 2287
Зарегистрирован: 13 фев 2004, 18:14
Откуда: СПб
Контактная информация:

Думаю тут есть ещё один момент:

Пример:
x=0.99; y=0.0101;
z=1/y;
z=(z*(1-x));

Два из трёх программистов дадут ответ z==0.99. Физик или бухгалтер даст ответ 1. Разница в ответах в изначально выбранной точности вычислений.
Даже самый дурацкий замысел можно воплотить мастерски
Defder
Сообщения: 64
Зарегистрирован: 24 май 2005, 12:25

Eugie, а ты в этом уверен?
Если это и так, то, думаю, не во всех сопроцессорах. А во вторых, процессор должен ещё получить данные из памяти. Вообще, надо бы провести тест производительности.
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

По топику:
Для бизнес расчетов я бы вообще не стал использовать плавающую точку.
Только расчеты на рациональных числах либо на фиксированной точке. Либо на чем-то типа BigDecimal(java)

Использовал бы я их для графики ...или для физического движка... короче лучше всего для мультимедиа или игр.

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

float vs double: В общем-то производительность одинаковая. Более того, мат. сопроцессор внутри себя манипулирует не 64-битовыми double, а 80-битовыми вещественными числами.
Если это и так, то, думаю, не во всех сопроцессорах
Какие мат.сопроцессоры ты знаешь кроме тех, что встроены в пентиум?
2B OR NOT(2B) = FF
Eugie
Сообщения: 708
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

float vs double: В общем-то производительность одинаковая. Более того, мат. сопроцессор внутри себя манипулирует не 64-битовыми double, а 80-битовыми вещественными числами.
Согласен, для x86. Для RISC'ов все-таки 32 или 64, точно не помню.
Насчет производительности надо, конечно, тестировать. Так что классик прав, на этом и сойдемся :)
Defder
Сообщения: 64
Зарегистрирован: 24 май 2005, 12:25

#include <iostream.h>
#include <conio.h>
#include <math.h>
#include <windows.h>

typedef {float|double} real;

const real pi=4*atan(1);

int main() {
int i,t;
real x=-1;
t=GetTickCount();
for (i=0;i<2000000;i++) {
x=sin(cos(x))*pi;
x=sin(cos(x))*pi;
x=sin(cos(x))*pi;
x=sin(cos(x))*pi;
x=sin(cos(x))*pi;
}
cout << x << endl;
cout << GetTickCount()-t << endl;
getch();
return 0;
}

Эта программа решает уравнение x=sin(cos(x))*pi в 10 млн. итераций (ответ: x=-2.14048). На Celeron 1.7 с типом double выполняется на ~10% дольше чем с float.
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

Это связано не с производительностью сопроцессора, а с тем, что 64-битовые значения более напряжно загружать-выгружать из памяти чем 32-х битовые
2B OR NOT(2B) = FF
Eugie
Сообщения: 708
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

Absurd, похоже на то.
Вот дизассемблированный код для x=sin(cos(x))*pi, как грицца, найдите разницу:

Код: Выделить всё

// если float
20:       x=sin(cos(x))*pi;
0040113C   fld         dword ptr [ebp-0Ch]
0040113F   sub         esp,8
00401142   fstp        qword ptr [esp]
00401145   call        _cos (004015f4)
0040114A   fstp        qword ptr [esp]
0040114D   call        _sin (00401544)
00401152   add         esp,8
00401155   fmul        dword ptr [pi (00430428)]
0040115B   fstp        dword ptr [ebp-0Ch]

// если double
20:       x=sin(cos(x))*pi;
00401133   mov         ecx,dword ptr [ebp-0Ch]
00401136   push        ecx
00401137   mov         edx,dword ptr [ebp-10h]
0040113A   push        edx
0040113B   call        _cos (00401594)
00401140   fstp        qword ptr [esp]
00401143   call        _sin (004014e4)
00401148   add         esp,8
0040114B   fmul        qword ptr [pi (00430428)]
00401151   fstp        qword ptr [ebp-10h]
Ответить