Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Преобразование UINT64 к REAL64
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Grizzzly
В наследство досталось много кода, написанного уволившимся программистом. Ищу ошибки, разбираюсь. Специфика программы в том, что код был изначально написан под TMS с фиксированной точкой, затем был перенесем на ARM7, где часть операций стала производиться с вещественными числами. Есть множество приведений типов.
Нашел баг.
Код
UINT64 p1, p2;
...
REAL64 Power = (REAL64)(p1-p2);

Когда разность получалась отрицательной, результат был неверный.
Корректно ли делать приведение типов так?
Код
Power = (REAL64)p1-(REAL64)p2;

Или нужно сначала разность привести к SINT64, а затем уже к REAL64?
smalcom
>> Power = (REAL64)p1-(REAL64)p2;
так верно
DpInRock
Изначально неверно использовать UINT для арифметических операций со знаком. Экономия одного бита при 64 разрядах вряд ли оправдана.
Grizzzly
Цитата(smalcom @ Mar 1 2014, 11:35) *
>> Power = (REAL64)p1-(REAL64)p2;
так верно

Спасибо!
У меня выходило, что этот вариант не всегда прокатывал.
В программе p1, p2 могут принимать значения в диапазоне от 50000 до нескольких десятков миллионов. Тут такое приведение типов срабатывало.
При тестировании взял такие значения: p1 = 800000000000000000, p2 = 800000000000000001. Тогда работает вариант
Код
UINT64 t = p[0]-p[1];
Power = (REAL64)((SINT64)t);
, а в первом случае ошибка.
Теперь понял, что так получалось из-за того, что в примере было больше 16 значащих десятичных цифр.

Цитата(DpInRock @ Mar 1 2014, 11:50) *
Изначально неверно использовать UINT для арифметических операций со знаком. Экономия одного бита при 64 разрядах вряд ли оправдана.

Согласен. Что досталось, с тем и пришлось работать...
maksimp
Цитата(Grizzzly @ Mar 1 2014, 14:08) *
При тестировании взял такие значения: p1 = 800000000000000000, p2 = 800000000000000001. Тогда работает вариант

Чтобы не терять точность в подобных случаях можно например так:
Код
Power = (p1>=p2) ? ((REAL64)(p1-p2)) : (-(REAL64)(p2-p1));

Фактически нужно 65-битную промежуточную переменную, и результат (p1>=p2) как раз хранит дополнительный бит.
Grizzzly
Цитата(maksimp @ Mar 1 2014, 21:23) *
Фактически нужно 65-битную промежуточную переменную, и результат (p1>=p2) как раз хранит дополнительный бит.

Спасибо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.