Плавающая запятая и разные процессоры

Вопросы программирования на Free Pascal, использования компилятора и утилит.

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

Плавающая запятая и разные процессоры

Сообщение unC0Rr » 16.01.2007 03:57:03

Здравствуйте!
Я столкнулся с проблемой, что на разных машинах по-разному вычисляются выражения с плавающей запятой. В связи с этим у меня возник вопрос, возможно ли сделать так, чтобы на разных процессорах получался одинаковый результат? Пробовал искать что-нибудь по теме, не нашёл решения для паскаля. Для gcc, видимо, ключик подойдёт -mieee-conformant.
Подскажите, пожалуйста, существует ли решение моей проблемы? Решат ли проблему вычисления с эмуляцией?
unC0Rr
новенький
 
Сообщения: 59
Зарегистрирован: 02.02.2006 03:44:44

Сообщение unC0Rr » 19.01.2007 21:00:58

Неужели я задал вопрос с настолько очевидным ответом, что всем лень даже объяснять? :)
unC0Rr
новенький
 
Сообщения: 59
Зарегистрирован: 02.02.2006 03:44:44

Сообщение Slavikk » 19.01.2007 21:48:38

На разных машинах это AMD - Intel, или Intel Pentium3 - Intel Pentium4?

Если это AMD - Intel, то читал что из-за разной архитектуры одни процессоры лучше считают точные цифры, другие с плавающей запятой. И у кого то из них проблемы были они один тип расчетов эмулировали через другой - и появлялась погрешность. Вроде так, точно непомню, врать не буду, могу и ошибаться.

Толь ответ тебе даст их официальные сайт с туториалами на английском (хорошо хоть не на албанском) и кодами скорее всего на С++ (но могут быть и на Асемблере).
Аватара пользователя
Slavikk
постоялец
 
Сообщения: 208
Зарегистрирован: 15.01.2007 22:34:52
Откуда: Из лесов...

Сообщение shade » 19.01.2007 22:35:52

Результаты нужно округлять, тогда проблемы могут быть только из-за недостаточной разрядности или численной неустойчивости алгоритма.
Аватара пользователя
shade
энтузиаст
 
Сообщения: 879
Зарегистрирован: 21.02.2006 20:15:48
Откуда: http://shamangrad.net/

Сообщение unC0Rr » 20.01.2007 19:04:29

Slavikk писал(а):На разных машинах это AMD - Intel, или Intel Pentium3 - Intel Pentium4?

На разных машинах - это от пентиума 1 до Core 2 Duo, от K6 до AMD64, также PowerPC и возможно другие процессоры.

Slavikk писал(а):из-за разной архитектуры одни процессоры лучше считают точные цифры, другие с плавающей запятой. И у кого то из них проблемы были они один тип расчетов эмулировали через другой - и появлялась погрешность.

"Точные" - это целые? Погрешность при рассчётах в целых числах? Ужос %)
unC0Rr
новенький
 
Сообщения: 59
Зарегистрирован: 02.02.2006 03:44:44

Сообщение unC0Rr » 20.01.2007 19:08:43

shade писал(а):Результаты нужно округлять, тогда проблемы могут быть только из-за недостаточной разрядности или численной неустойчивости алгоритма.

Округлять? Каким образом? Скажем, идёт рассчёт кривой Безье. Точки рисуются в битмапы, картинка получается разной. Чуть-чуть, буквально пара пикселов. При том что используется тип Extended... Я в растерянности.
unC0Rr
новенький
 
Сообщения: 59
Зарегистрирован: 02.02.2006 03:44:44

Сообщение Юра » 20.01.2007 19:42:09

На любом х86 процессоре результаты будут одинаковыми.
На других процессорах (PowerPC, ARM) нет типа Extended (80 bit). Там Extended=Double (64 bit).
Поэтому если нужны абсолютно одинаковые результаты на процессорах разной архитектуры нужно использовать тип Double.
Юра
постоялец
 
Сообщения: 163
Зарегистрирован: 25.05.2005 10:20:09
Откуда: Украина, Киев

Сообщение unC0Rr » 20.01.2007 19:46:40

Юра писал(а):На любом х86 процессоре результаты будут одинаковыми.

Почему-то получаются разные. Конкретно - пентиум4, 32-битный код и амд64, 64битный код. Пробовал типы Double и Extended, разница есть. Особенно обидно когда разница возникает при проверке условий больше-меньше, при этом работает разный код и конечные результаты получаются ещё более разными.
unC0Rr
новенький
 
Сообщения: 59
Зарегистрирован: 02.02.2006 03:44:44

Сообщение shade » 20.01.2007 20:10:14

unC0Rr писал(а):Особенно обидно когда разница возникает при проверке условий больше-меньше, при этом работает разный код и результаты получаются ещё более разными.

Условия нужно проверять с учетом погрешности:
Проверка на ноль
Код: Выделить всё
if abs(a) < e then ... else ...
где e - допустимая погрешность.
А аналогично для сравнения больше:
Код: Выделить всё
if a + e > b then ...
if a - b > e then ...
if a - b > -e then...

меньше:
Код: Выделить всё
if a - e < b then ...
if a - b < e then ...
if a - b < -e then ...

или что-то в этом духе, точные формы не припомню.

unC0Rr писал(а):Чуть-чуть, буквально пара пикселов.

Один-в-один врядли добьешься, но может удасться улучшить результат до погрешности в пол пикселя. Вопрос в том как вычисляешь, как преобразуешь действительное к целому.
Попробуй для расчетов и использовать другой масштаб (смысл в том чтобы увеличить точность в расчетах с плавающей точкой):
например (x, y) - целочисленные координаты, а (u, v) - соответствующие действительные координаты.
Преобразование u := 2 * x; v := 2 * y; обратное: x := Round(u / 2), y := Round(v / 2)
или x := Round(u) div 2; y := Round(v) div 2;
По экспериментируй с другим множителем...
Аватара пользователя
shade
энтузиаст
 
Сообщения: 879
Зарегистрирован: 21.02.2006 20:15:48
Откуда: http://shamangrad.net/

Сообщение unC0Rr » 20.01.2007 20:16:13

shade писал(а):Условия нужно проверять с учетом погрешности:
Проверка на ноль
Код: Выделить всё
if abs(a) < e then ... else ...
где e - допустимая погрешность.
А аналогично для сравнения больше:
Код: Выделить всё
if a + e > b then ...
if a - b > e then ...
if a - b > -e then...

меньше:
Код: Выделить всё
if a - e < b then ...
if a - b < e then ...
if a - b < -e then ...

или что-то в этом духе, точные формы не припомню.

Да, начитался я таких советов :) Только они же не помогают всё равно :) Какая разница, напишу я (x > 0) или (x > e), если x разный получается :) Вот ещё пример кода из моей программы:
Код: Выделить всё
if (tx - Gear1^.X) * (ty - Gear2^.Y) > (tx - Gear2^.X) * (ty - Gear1^.Y) then ...

Куда тут погрешности вставить и чем они могут помочь? имхо, ничем :(
unC0Rr
новенький
 
Сообщения: 59
Зарегистрирован: 02.02.2006 03:44:44

Сообщение shade » 20.01.2007 20:18:26

Хотя, нет один-в-один в принципе добиться можно... но зачем?
Аватара пользователя
shade
энтузиаст
 
Сообщения: 879
Зарегистрирован: 21.02.2006 20:15:48
Откуда: http://shamangrad.net/

Сообщение shade » 20.01.2007 20:20:12

Код: Выделить всё
if (tx - Gear1^.X) * (ty - Gear2^.Y) - (tx - Gear2^.X) * (ty - Gear1^.Y) > -e then ...
:wink:
Аватара пользователя
shade
энтузиаст
 
Сообщения: 879
Зарегистрирован: 21.02.2006 20:15:48
Откуда: http://shamangrad.net/

Сообщение unC0Rr » 20.01.2007 20:22:02

Зачем одинаковые результаты при вычислениях? :) Дело в том, что компьютеры взаимодействуют по сети, и при разных результатах вычислений взаимодействие невозможно. Выполнять вычисления только на одной машине невозможно, трафик при этом может составлять несколько мегабайт в секунду, а использовать приложение предполагается посредством интернета.
unC0Rr
новенький
 
Сообщения: 59
Зарегистрирован: 02.02.2006 03:44:44

Сообщение shade » 20.01.2007 20:23:53

Извени, то было >=
а просто >
shade писал(а):
Код: Выделить всё
if (tx - Gear1^.X) * (ty - Gear2^.Y) - (tx - Gear2^.X) * (ty - Gear1^.Y) > +e then ...
:wink:
Аватара пользователя
shade
энтузиаст
 
Сообщения: 879
Зарегистрирован: 21.02.2006 20:15:48
Откуда: http://shamangrad.net/

Сообщение unC0Rr » 20.01.2007 20:24:40

shade писал(а):
Код: Выделить всё
if (tx - Gear1^.X) * (ty - Gear2^.Y) - (tx - Gear2^.X) * (ty - Gear1^.Y) > -e then ...
:wink:

Т.е.
Код: Выделить всё
if (tx - Gear1^.X) * (ty - Gear2^.Y) > (tx - Gear2^.X) * (ty - Gear1^.Y) + e then ...

??? :) А в чём тайный смысл? :)
unC0Rr
новенький
 
Сообщения: 59
Зарегистрирован: 02.02.2006 03:44:44

След.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

Рейтинг@Mail.ru