Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
r_o_o_t
Зарегистрирован: 19.07.2005 Сообщения: 3
|
Добавлено: Вт Июл 19 2005 16:49 Заголовок сообщения: So strange float computations |
|
|
Hi everybody.
Unfortunately I cannot type in Russian but I can read.
I have changed all doubles to float in my c++ code which perform some scientific computations to increase the spead and memory requirements. And I've faced a very strange behaviour. In fact I cannot compare one float with another with != operator.
Here is the sample code which illustrates this situation:
#include <stdlib.h>
void main()
{
float a=0.0089f;
float b=0.0087f;
float zero=b-a+0.0002f; // do you think it would be zero?
// no, it is 3.34694e-010 )
if(b!=(a+0.0002f)) abort();
}
The compiler is MSVC.
Does anybody have any idea about this trouble?
Thanks in advance! |
|
Вернуться к началу |
|
|
r_o_o_t
Зарегистрирован: 19.07.2005 Сообщения: 3
|
Добавлено: Вт Июл 19 2005 17:02 Заголовок сообщения: Sorry, the right line is: if(b!=(a-0.0002f)) abort(); |
|
|
It's just a mistype, the question is the same |
|
Вернуться к началу |
|
|
CrazyWizard
Зарегистрирован: 18.04.2005 Сообщения: 12
|
Добавлено: Ср Июл 20 2005 08:49 Заголовок сообщения: |
|
|
Насколько я понял, то не (b!=(a+0.0002f)), а (a!=(b+0.0002f)).
Или ошибка в другом? |
|
Вернуться к началу |
|
|
Kefir
Зарегистрирован: 16.04.2005 Сообщения: 443 Откуда: Пермь
|
Добавлено: Ср Июл 20 2005 10:32 Заголовок сообщения: |
|
|
Да, здесь видать одни системщики. Привет от численников! В любом учебнике по программирования сказано что следует избегать сранений типа =, != для чисел с плавающей запятой. Из-за ошибок вычисления, т.к. в абсолютном большинстве случаев эти числа будут неравны. Более того от перестановки мест слагаемых сумма изменяется и еще много чего интересного. А если действительно нужно узнать равны ли числа, то нужно сделать примерно так:
Код: |
float a = 1+0.1;
float b = 1.1;
if(abs(a-b)<0.00001)...; |
Вот так. |
|
Вернуться к началу |
|
|
r_o_o_t
Зарегистрирован: 19.07.2005 Сообщения: 3
|
Добавлено: Ср Июл 20 2005 15:40 Заголовок сообщения: |
|
|
Спасибо за ответ. Это всё, конечно, да. Но вот с даблом всё ж ведь работало как часы - там только сложение, вычитание и умножение на целые числа. И на флоат я перехожу для увеличения скорости. А если везде fabs(a-b)<... написать, то быстродействие - наоборот - упадёт.
И потом, если бы я, например, корень извлёк, а потом - в квадрат, то понятно, тут же - почти целые числа, больше чем четвёртого знака после запятой нет и быть не может. |
|
Вернуться к началу |
|
|
DmitryShm
Зарегистрирован: 17.11.2003 Сообщения: 211 Откуда: Казань
|
Добавлено: Чт Июл 21 2005 15:44 Заголовок сообщения: используй |
|
|
Используй длинную арифметику. На олимпиадах когда задачки на большие вычисления возникали, то все подготовленные школьники использовали длинную арифметику. Сейчас реализаций этих библиотек с длинными числами (очень длинными) немерянно. Или используй ядро вычислительной системы наконец. Например, Mathematica. _________________ love IT |
|
Вернуться к началу |
|
|
Kefir
Зарегистрирован: 16.04.2005 Сообщения: 443 Откуда: Пермь
|
Добавлено: Пт Июл 22 2005 07:24 Заголовок сообщения: |
|
|
С double работало потому как там точность выше. Вот и все объяснение. При переходе на float скорость скорее упадет, т.к. в FPU все вычисления один ...(в смысле, все равно) выполняются над double'ами. Если только компилятор не будет задействовать SSE. А будет он их задействовать или нет, кто его знает. Единственная выгода от использования float это уменьшение расхода памяти, что на мой взгляд, сегодня неактуально.
А увеличение скорости вычислений путем введения потенциальной ошибки, мне кажется глупо?
Увеличения скорости надо добиваться другими методами, например вынесение операций за пределы цикла... |
|
Вернуться к началу |
|
|
|