Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« : 03-08-2007 15:39 » |
|
простой, казалось бы , вопрос...
как отследить факт потери точности после очередной операции умножения или деления числа типа double ?
(дело в том, что переполнение я не могу отследить на СИ)
|
|
« Последнее редактирование: 05-08-2007 12:25 от Алексей1153++ »
|
Записан
|
|
|
|
PooH
Глобальный модератор
Offline
Пол:
... и можно без хлеба!
|
|
« Ответ #1 : 03-08-2007 15:50 » |
|
приведи пример...
попробуй сделать обратную операцию и сравнить с оригиналом.
|
|
|
Записан
|
Удачного всем кодинга! -=x[PooH]x=-
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #2 : 03-08-2007 16:01 » |
|
PooH, про обратную операцию это я думал, только вспомнил ещё тему про сравнение вещественных чисел, когда оказывалось, что 0.0 иногда != 0.0 , то есть и там надо сравнивать с некой точностью, вроде всё таки как-то иначе надо. А кроме того - время на вычисления, получится время в 2 раза больше, а во как бы узнать о переполнении мантиссы уже во время операции, может вставку на асме ?
|
|
« Последнее редактирование: 05-08-2007 12:25 от Алексей1153++ »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #3 : 03-08-2007 16:03 » |
|
собственно, вопрос возник откуда - взялся за сжатие информации при помощи арифметического кодирования
|
|
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #4 : 04-08-2007 07:25 » |
|
Алексей1153++, а тебе точно нужны числа с плавающей точкой, если ты занимаешься кодированием?
|
|
|
Записан
|
Странно всё это....
|
|
|
PooH
Глобальный модератор
Offline
Пол:
... и можно без хлеба!
|
|
« Ответ #5 : 04-08-2007 09:48 » |
|
может вставку на асме а привыполнении операций на С разве флаг переполнения не устанавливается?
|
|
|
Записан
|
Удачного всем кодинга! -=x[PooH]x=-
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #6 : 04-08-2007 14:31 » |
|
LogRus, да, в арифметическом кодировани есть такая фигня ) , там масштабируется интервал , числа используются вещественные
PooH, в СИ почему то нету CarryFlag вообще (именно на уровне СИ) , это часто неудобно... И загадка - почему разработчики языка так грубо обошлись с флагом
|
|
« Последнее редактирование: 05-08-2007 12:26 от Алексей1153++ »
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #7 : 04-08-2007 15:57 » |
|
И загадка - почему разработчики языка так грубо обошлись с флагом
Чтобы все со временем перешли на .НЕТ
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
Finch
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #8 : 04-08-2007 16:19 » |
|
PooH, в СИ почему то нету CarryFlag вообще (именно на уровне СИ) , это часто неудобно... И загадка - почему разработчики языка так грубо обошлись с флагом
Наверно потому что, это не стандартная вешь для всех процессоров. Многие конструкции языка построены на основе команд PDP11.
|
|
|
Записан
|
Не будите спашяго дракона. Джаффар (Коша)
|
|
|
nikedeforest
|
|
« Ответ #9 : 04-08-2007 17:37 » |
|
Если уж очень надо отследить переполнение, то можно попробовать создать пользовательский тип на основе int. Создай класс и в нем переменную int, ну и перегрузи операции.
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #10 : 05-08-2007 05:51 » |
|
nikedeforest, про .НЕТ - это ты , конечно, глупость сморозил nikedeforest, ну а с int проблем нету, после операции можно просто проверить n&0x80000000 в нужный момент. Я говорю о вещественных типах
|
|
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #11 : 05-08-2007 06:39 » |
|
Глупость или не глупость, а отследить переполнение там можно встроенными инструментами. Ну тоже самое и с вещественным типом. Ты проверку же не будешь тащить по всему коду, ее лучше осуществить внутри класса, правда ведь
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #12 : 05-08-2007 11:26 » |
|
nikedeforest, можно и внутри класса. Только прикол в том, что это всего 1 (один) раз нужно сделать (в этом алгоритме). А больше я никогда и нигде не встречал задачи контроля точности )
|
|
« Последнее редактирование: 05-08-2007 11:34 от Алексей1153++ »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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++ »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #14 : 05-08-2007 15:43 » |
|
собственно, ошибку понял - парюсь с пониманием формата представления типа double ))
1 самый старший бит - знак числа 10 следующих - характеристика 53 младших бита - мантисса
что есть характеристика числа ?
|
|
« Последнее редактирование: 05-08-2007 15:46 от Алексей1153++ »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #15 : 05-08-2007 16:08 » |
|
во. придумал. Ну нафик всю замуту с представлением числа и вытекающем из этого. d3=операция(d1,d2);
d4=обратная операция(d1,d2);
//сравниваем if( *((__int64*)&d3) != *((__int64*)&d4) ) { //потеря точности }
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #16 : 06-08-2007 05:56 » |
|
Если ориентироваться только на x86 процессоры, то есть такая фича FPU, как генерация прерывания при потере точности результатом. Правда, я не уверен, можно ли это использовать в современных ОС - нужно доки посмотреть на необходимые права для доступа к регистру управления FPU.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #17 : 06-08-2007 06:13 » |
|
Ром, сильно привязываться к аппаратной части не хочется. Кстати, провёл тест в экселе (с использованием float) результат обнадёжил ) Цифры не запомнил, вечером напишу. Приступаю к реализации арифметического кодирования )
|
|
|
Записан
|
|
|
|
|