Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: потеря точности double или float  (Прочитано 25596 раз)
0 Пользователей и 9 Гостей смотрят эту тему.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« : 03-08-2007 15:39 » 

простой, казалось бы , вопрос...

как отследить факт потери точности после очередной операции умножения или деления числа типа double ?

(дело в том, что переполнение я не могу отследить на СИ)
« Последнее редактирование: 05-08-2007 12:25 от Алексей1153++ » Записан

PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #1 : 03-08-2007 15:50 » 

приведи пример...

попробуй сделать обратную операцию и сравнить с оригиналом.
Записан

Удачного всем кодинга! -=x[PooH]x=-
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #2 : 03-08-2007 16:01 » 

PooH, про обратную операцию это я думал, только вспомнил ещё тему про сравнение вещественных чисел, когда оказывалось, что 0.0 иногда != 0.0 , то есть и там надо сравнивать с некой точностью, вроде
Код:
 модуль(a-b) < точность

всё таки как-то иначе надо. А кроме того - время на вычисления, получится время в 2 раза больше, а во как бы узнать о переполнении мантиссы уже во время операции, может вставку на асме ?
« Последнее редактирование: 05-08-2007 12:25 от Алексей1153++ » Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 03-08-2007 16:03 » 

собственно, вопрос возник откуда - взялся за сжатие информации при помощи арифметического кодирования
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #4 : 04-08-2007 07:25 » 

Алексей1153++, а тебе точно нужны числа с плавающей точкой, если ты занимаешься кодированием?
Записан

Странно всё это....
PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #5 : 04-08-2007 09:48 » 

Цитата
может вставку на асме
а привыполнении операций на С разве флаг переполнения не устанавливается?
Записан

Удачного всем кодинга! -=x[PooH]x=-
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 04-08-2007 14:31 » new

LogRus, да, в арифметическом кодировани есть такая фигня ) , там масштабируется интервал , числа используются вещественные

PooH, в СИ почему то нету CarryFlag вообще (именно на уровне СИ) , это часто неудобно... И загадка - почему разработчики языка так грубо обошлись с флагом
« Последнее редактирование: 05-08-2007 12:26 от Алексей1153++ » Записан

nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 04-08-2007 15:57 » 

Цитата
И загадка - почему разработчики языка так грубо обошлись с флагом
Чтобы все со временем перешли на .НЕТ Улыбаюсь
Записан

ещё один вопрос ...
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #8 : 04-08-2007 16:19 » 

PooH, в СИ почему то нету CarryFlag вообще (именно на уровне СИ) , это часто неудобно... И загадка - почему разработчики языка так грубо обошлись с флагом

Наверно потому что, это не стандартная вешь для всех процессоров. Многие конструкции языка построены на основе команд PDP11. 
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 04-08-2007 17:37 » 

Если уж очень надо отследить переполнение, то можно попробовать создать пользовательский тип на основе int. Создай класс и в нем переменную int, ну и перегрузи операции.
Записан

ещё один вопрос ...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #10 : 05-08-2007 05:51 » 

nikedeforest, про .НЕТ - это ты , конечно, глупость сморозил Улыбаюсь

nikedeforest, ну а с int проблем нету, после операции можно просто проверить n&0x80000000 в нужный момент.
Я говорю о вещественных типах
Записан

nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 05-08-2007 06:39 » 

Глупость или не глупость, а отследить переполнение там можно встроенными инструментами.
Ну тоже самое и с вещественным типом. Ты проверку же не будешь тащить по всему коду, ее лучше осуществить внутри класса, правда ведь Ага
Записан

ещё один вопрос ...
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #12 : 05-08-2007 11:26 » 

nikedeforest, можно и внутри класса. Только прикол в том, что это всего 1 (один) раз нужно сделать (в этом алгоритме). А больше я никогда и нигде не встречал задачи контроля точности )
« Последнее редактирование: 05-08-2007 11:34 от Алексей1153++ » Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 05-08-2007 12:20 » 

как бы вот какие мысли : (учитывая, что мантисса double - младшие 52 бита)
(без обратного умножения/деления всё же не обойтись Жаль )
Код:
double d1;//первое число
double d2;//второе
double d3;//результат операции

__int64 mask=(((__int64)1)<<53)-1;

__int64 n1;
__int64 n2;
__int64 n3;

//проверка переполнения double при умножении
{
d1=...;
d2=...;

//основная операция
d3=d1*d2;

//проверка
n1=*((__int64*)&d1);
n2=*((__int64*)&d2);
n3=*((__int64*)&d3);
if( ((n1*n2)&mask) != (n3&mask) )
{
//переполнение при умножении

int nnn;//для остановки в дебаге
}
}

//проверка переполнения double при делении
{
d1=...;
d2=...;

//основная операция
d3=d1/d2;

//проверка
n1=*((__int64*)&d1);
n2=*((__int64*)&d2);
n3=*((__int64*)&d3);
if( ((n1/n2)&mask) != (n3&mask) )
{
//переполнение при делении

int nnn;//для остановки в дебаге
}
}

только что то я всё же не учёл ... Потому что не работает ))

потому что, 4503599627370495.0 * 1.0 не должно давать переполнение, а оно даёт
« Последнее редактирование: 05-08-2007 15:47 от Алексей1153++ » Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #14 : 05-08-2007 15:43 » 

собственно, ошибку понял - парюсь с пониманием формата представления типа double ))

1 самый старший бит - знак числа
10 следующих - характеристика
53 младших бита - мантисса

что есть характеристика числа ?
« Последнее редактирование: 05-08-2007 15:46 от Алексей1153++ » Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 05-08-2007 16:08 » 

во. придумал. Ну нафик всю замуту с представлением числа и вытекающем из этого.
Код:

d3=операция(d1,d2);

d4=обратная операция(d1,d2);

//сравниваем
if( *((__int64*)&d3) != *((__int64*)&d4) )
{
   //потеря точности
}
Записан

RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #16 : 06-08-2007 05:56 » 

Если ориентироваться только на x86 процессоры, то есть такая фича FPU, как генерация прерывания при потере точности результатом. Правда, я не уверен, можно ли это использовать в современных ОС - нужно доки посмотреть на необходимые права для доступа к регистру управления FPU.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #17 : 06-08-2007 06:13 » 

Ром, сильно привязываться к аппаратной части не хочется.
Кстати, провёл тест в экселе (с использованием float) результат обнадёжил ) Цифры не запомнил, вечером напишу.
Приступаю к реализации арифметического кодирования )
Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines