Собственно шаблон класса для предсталения чисел с фиксированной точкой. Определены все основные арифметические операции, преобразование к типам double / float. Доступны методы: integer(), fractional(), float(), ceil(), round(). Интерестно узнать ваше мнение.
Здравствуйте, Nose, Вы писали:
N>Они хороши тем, что ошибка предсказуема и управляема. N>У меня диплом был по разработке методов шифрования — так вот числа с фиксированной точкой там незаменимы.
у меня частью диплома была балансировка движения самолета в пространстве, из всего запомнил хорошо только одно : при использовании float вместо double, тоесть при урезании точности, на первой минуте полета приходилось раздавать всем члена экипажа парашуты
Здравствуйте, WinterMute, Вы писали:
WM>Собственно шаблон класса для предсталения чисел с фиксированной точкой. Определены все основные арифметические операции, преобразование к типам double / float. Доступны методы: integer(), fractional(), float(), ceil(), round(). Интерестно узнать ваше мнение.
я вот только не понял, где это может применятся?
обычно ведь вычисления ведуться для чисел с максимальной точностью, для уменьшения накапливания ошибки, а если числа обрезать, то и ошибка будет больше накапливаться.
помоему фиксировать точку необходимо только для выводе ресультата пользователю, что вполне решимо стандартными средствами.
Здравствуйте, ssm, Вы писали:
sm>я вот только не понял, где это может применятся? ssm>обычно ведь вычисления ведуться для чисел с максимальной точностью, для уменьшения накапливания ошибки, а если числа обрезать, то и ошибка будет больше накапливаться. ssm>помоему фиксировать точку необходимо только для выводе ресультата пользователю, что вполне решимо стандартными средствами.
Числа с фиксированной точкой бывают нужны когда очень важна скорость и не очень важна точность. Например, они могут пригодится в реализации алгоритма Брезенхема, для рисования линий с субпиксельной точностью. Еще, у floating point чисел есть одна неприятная особенность: они хранятся с точностью +/- EPS, где EPS какая-то маленькая величина. Т.е., если я правильно понял, даже если написать:
Еще не смотрел детально но по названию то что нужно
еще бы развернутый пример использования...
Кстати под GBA компилить не пробовал случайно? имхо там это просто находка.
и вообще, под GCC компилится?
Здравствуйте, yxiie, Вы писали:
Y>Здравствуйте, WinterMute, Вы писали:
Y>...
Y>Еще не смотрел детально но по названию то что нужно Y>еще бы развернутый пример использования... Y>Кстати под GBA компилить не пробовал случайно? имхо там это просто находка. Y>и вообще, под GCC компилится?
Компилироватся должно везде, никаких трюков не используется, только простая арифметика. Есть один возможный подводный камень: дробная и целая части, получаемые соответственно методами integer() и fractional(), всегда должны быть одного знака, Целая часть получается операцией m_value/scale, а дробная операцией m_value%scale. Мой английский не очень хорош, и я не понял, всегда-ли гарантируется что результат операции % будет того-же знака что и результат деления. Если нет, то плохо.
Реализовано следующим образом: всё чило хранится в переменной типа "Type". Для этого типа определены все основные арифметические операции, но второй операнд должен быть одним из следующих типов: Base, fixed_T, double, float. Пример использования:
typedef fixed_T<int, 8> fixed; // используем в качестве контейнера число типа int, для хранения дробной части отводим 8 бит
fixed a(1.5);
fixed b(-1.5);
int integer = a.integer(); // == 1int fractional = a.fractional(); // == 128
integer = b.integer(); // == -1
fractional = b.fractional(); // == -128int some = a; // == 2; преобразование к Base происходит с округлением, а не с отсечением дробной части
a++;
a *= 5.5f;
int ceil = a.ceil(); // == 2int floor = a.floor(); // == 1int round = a.round(); // == 2
a /= 5;
a /= UINT(5); // ошибка, компилятор не знает к чему преобразовать UINT(5) -- к Base? double? float?
a /= fixed::value_type( UINT(5) ); // ОК
Здравствуйте, ssm, Вы писали:
ssm>я вот только не понял, где это может применятся? ssm>обычно ведь вычисления ведуться для чисел с максимальной точностью, для уменьшения накапливания ошибки, а если числа обрезать, то и ошибка будет больше накапливаться. ssm>помоему фиксировать точку необходимо только для выводе ресультата пользователю, что вполне решимо стандартными средствами.
Они хороши тем, что ошибка предсказуема и управляема.
У меня диплом был по разработке методов шифрования — так вот числа с фиксированной точкой там незаменимы.
Здравствуйте, ssm, Вы писали:
ssm>у меня частью диплома была балансировка движения самолета в пространстве, из всего запомнил хорошо только одно : при использовании float вместо double, тоесть при урезании точности, на первой минуте полета приходилось раздавать всем члена экипажа парашуты
Да не вопрос
Очевидно, что в твоем случае числа fixed-point неприменимы.
В моем случае были неприменимы числа с плавающей точкой.
Здравствуйте, ssm, Вы писали:
ssm>у меня частью диплома была балансировка движения самолета в пространстве, из всего запомнил хорошо только одно : при использовании float вместо double, тоесть при урезании точности, на первой минуте полета приходилось раздавать всем члена экипажа парашуты
А я видел физику реализованую на float'ах. Прикол был в том что когда система приходила в состояние близкое к покою то производительность резко проседала. Происходило это из-за того что скорости объектов становились очень маленькими, а float'ы с маленькими числами работают не просто медленно, а очень медленно. С фиксированой точкой такого бы не произошло ибо скорости бы просто обнулились.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Ka3a4oK, Вы писали:
KK>Будет ли выигрыш в скорости при использованиии фиксированной точки (по сравеннию с плавающей) на современных процессорах (Pentium 4) ?
WM>Точно не знаю, но думаю что будет и значительный.
Ну а если серьёзно, заявление совершенно голословное, сильно рекомендую проверить свои слова.
Кроме того, операция умножения "Самое большое представимое целое число * 0.9999 (т.е. самое большое дробное число < 1)" даст переполнение и как результат — неправильный результат.
Тоже самое с делением:
0111111111000000.........
делим на
0111111111100000.........
вы в rem*scale также получите переполнение и неправильный результат..
Если вы реализуете более точные вычисления то количество целочисленных операций и битовых сдвигов заставит усомниться вас в скорости fixed_point класса, для P4 (учтите что double-ы считаются одной командой на процессоре), и даже для embedded машин (имхо деление 2х float-ов всё таки реализуется гораздо проще даже программно — поделил мантиссы, вычел экспоненты, всё сложил назад).
WH>Происходило это из-за того что скорости объектов становились очень маленькими, а float'ы с маленькими числами работают не просто медленно, а очень медленно.
Интересно!
А как зависит скорость операций с числами с плавающей точкой от значения мантиссы? Я наверное чего-то не понимаю...
Здравствуйте, Ka3a4oK, Вы писали:
KK>Будет ли выигрыш в скорости при использованиии фиксированной точки (по сравеннию с плавающей) на современных процессорах (Pentium 4) ?
Скорее всего нет , на (Pentium 4) почти уверен что нет.
А вот на платформах типа ARM — запросто (до 10 раз)!
KK>>Будет ли выигрыш в скорости при использованиии фиксированной точки (по сравеннию с плавающей) на современных процессорах (Pentium 4) ?
M>Скорее всего нет , на (Pentium 4) почти уверен что нет.
Не могу разделить эту уверенность, по крайней мере не посмотрев на результаты тестов. Всё-таки даже в 4-м пне — сопроцессор хоть и быстрый, но ALU-то лупит на удвоенной частоте. Ну и целочисленных конвейеров ЕМНИП поболе чем конвейеров для плавающей точки. Да и исполнение одной команды сопроцессора за один такт — бывает только в случае "идеальной" загрузки сопроцессора (на самом деле тактов-то будет поболе, просто несколько команд будут выполянтся одновременно за счёт конвейера).
PS. Вот если бы это добро (fixed point) положить на MMX/SSE — вот где счастье-то было-бы!