Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.93/15: Рейтинг темы: голосов - 15, средняя оценка - 4.93
taras atavin
4204 / 1766 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
1

Как определить порядок бит в double?

24.12.2014, 15:45. Просмотров 2737. Ответов 47
Метки нет (Все метки)

Как определить порядок бит в double?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.12.2014, 15:45
Ответы с готовыми решениями:

Too few parametrs in call to '_fastcall LogN(cont log double, const long double)'
void __fastcall TForm1::Button1Click(TObject *Sender) {int n; double...

Ошибка e2015 ambiguity between(double,double) в функции
Функция: void gmdh1() ; { double poly; double work; unsigned short int...

Как удалить один бит из числа?
Как программно сделать то, что на картинке?

Как обьявить и инициализировать массив через new в 32 бит?
Как объявить и инициализировать массив через new в 32 бит? На 64 бит вот...

Как вывести double в string
Стало не хватать int, решил воспользоваться double выводил раньше так: int...

47
DukeNukem
Заблокирован
24.12.2014, 16:24 2
https://ru.wikipedia.org/wiki/%D0%A7...81%D1%82%D0%B8
 Комментарий модератора 
Правило п 5.20 Запрещено публиковать ответы на вопросы или решения задач с форума на другие сайты и давать на них ссылки в качестве ответа.
0
taras atavin
4204 / 1766 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
24.12.2014, 17:03  [ТС] 3
Число́ двойно́й то́чности (Double precision, Double) — компьютерный формат представления числа с плавающей запятой, занимающий в памяти 64 бита, или 8 байт. Как правило, обозначает числа с плавающей запятой стандарта IEEE 754.
Меня не устраивает "как правило". А если на машине одного юзверя не IEEE 754, а у другого как раз именно IEEE 754? При попытке обменяться файлами, данные будут прочитаны не правильно. Как определить? Или как гарантированно преобразовать внутреннее представление в IEEE 754 и IEEE 754 во внутреннее представление?
0
Ilot
Эксперт С++
1831 / 1189 / 342
Регистрация: 16.05.2013
Сообщений: 3,139
Записей в блоге: 5
Завершенные тесты: 1
24.12.2014, 17:30 4
taras atavin, обрабатывайте:
C++
1
2
if(std::numeric_limits<double>::is_iec559 == true)
    ...
0
Kastaneda
Jesus loves me
Эксперт С++
4940 / 3016 / 346
Регистрация: 12.12.2009
Сообщений: 7,612
Записей в блоге: 2
Завершенные тесты: 1
24.12.2014, 17:38 5
Цитата Сообщение от taras atavin Посмотреть сообщение
А если на машине одного юзверя не IEEE 754, а у другого как раз именно IEEE 754? При попытке обменяться файлами, данные будут прочитаны не правильно.
Можно число в строке хранить, типа "123.345", после прочтения конвертировать в double.
0
taras atavin
4204 / 1766 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
24.12.2014, 17:43  [ТС] 6
А в бинарном? А то как то эта десятичная пахнет искажениями при каждом сохранении/загрузке файла, а если отводить по целому байту на двоичную цифру, то получится громоздко.

Добавлено через 2 минуты
Цитата Сообщение от Ilot Посмотреть сообщение
if(std::numeric_limits<double>::is_iec559 == true)
Допустим. А если false, то закрывать приладу?
0
Kastaneda
Jesus loves me
Эксперт С++
4940 / 3016 / 346
Регистрация: 12.12.2009
Сообщений: 7,612
Записей в блоге: 2
Завершенные тесты: 1
24.12.2014, 22:38 7
Хранить знак, мантису и порядок в int'ах. При чтении собирать в double.

Вопрос чисто ради интереса или программа реально разрабатывается под не IEEE 754?
0
taras atavin
4204 / 1766 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
25.12.2014, 05:27  [ТС] 8
Я вообще не знаю, что будет у пользователя. А как узнать количество бит порядка и мантисы?
0
Fulcrum_013
1588 / 1071 / 124
Регистрация: 14.12.2014
Сообщений: 8,822
Завершенные тесты: 3
25.12.2014, 06:59 9
Цитата Сообщение от taras atavin Посмотреть сообщение
Я вообще не знаю, что будет у пользователя. А как узнать количество бит порядка и мантисы?
Собираешь ручками из интов любую константу и сравниваешь с заданной в double. если не совпало - меняешь количество бит в порядке и т.д. пока не совпадет. Это если надо узнать какой формат у тебя в приладе, хотя это можно просто продефайнить под каждый таргет. Если надо в файле - то соответственно то же самое, только надо знать значение хотя бы одного из double в файле, хотя в таком случае проще писать интом в начале файла количество бит мантиссы и порядка.
0
taras atavin
4204 / 1766 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
25.12.2014, 07:04  [ТС] 10
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Собираешь ручками из интов любую константу и сравниваешь с заданной в double. если не совпало - меняешь количество бит в порядке и т.д. пока не совпадет.
Не понял. Какой заданной?
0
Fulcrum_013
1588 / 1071 / 124
Регистрация: 14.12.2014
Сообщений: 8,822
Завершенные тесты: 3
25.12.2014, 07:33 11
к примеру задаешь
C++
1
2
3
4
5
6
const double a=123.456;
//и делаешь функцию:
double MakeFloat(int IntegerPart, int DecimalPart, int PowerBits);
//ну а дальше
int PowerBits=1;
while(MakeFloat(123,456,PowerBits++)!=a);
0
taras atavin
4204 / 1766 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
25.12.2014, 07:39  [ТС] 12
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Это если надо узнать какой формат у тебя в приладе, хотя это можно просто продефайнить под каждый таргет. Если надо в файле - то соответственно то же самое,
Есть прилада, она сохраняет файл, в памяти было какие то числа типа double, эти числа пишутся в файл. Потом файл читается, возможно на другой машине, возможно другим приложением. Спецификация формата будет выложена в сетке, если стороннее приложение должно его поддерживать, читайте и соблюдайте. Требуется перед самими числами сохранить sizeof(double), отведя на него 64 бита. Перед этим полем уже размещёны префиксные коды и текстовое поле в семибитном ascii. Конечно очень весело грузить с диска текст, в котором символы не кратны байту, но это уже реализовано. А после sizeof(double) надо записать разрядности мантиссы и порядка, порядок частей числа, включая его знак, веса каждого бита, поддерживается ли нормализованная и денормализованная формы и каким именно кодом, хранятся ли мантиссы отрицательных чисел в прямом, или дополнительном коде, а только потом сами числа. Приложение, которое читает файл, должно прочитать все эти разрядности и порядки, потом прочитать сами числа и преобразовать их в некоторое внутреннее представление, а при сохранении файла сохранить все числа уже в своём внутреннем представлении и тоже перед этим записать sizeof(double), разрядности разрядности мантиссы и порядка, порядок частей числа, включая его знак, веса каждого бита, поддерживается ли нормализованная и денормализованная формы и каким именно кодом, хранятся ли мантиссы отрицательных чисел в прямом, или дополнительном коде. Ну знаете, как tiff может хранить данные и в little-endian, и в big-endian. Вот то самое нужно для double. Для целых понятно: сохранить разрядность числа и порядок байт, причём, порядок байт можно закодировать числом той же разрядности, в котором каждый байт равен его порядку по старшенству. То есть, например, для восьмибайтных чисел порядок - это число 0706050403020100 hex, если при чтении файла прочиталось 0001020304050607 hex, 0302010007060504 hex, 0405060700010203 hex, или любое другое значение кода порядка, то для преобразования восьмибайтных числе во внутреннее представление их надо подвергнуть такой же перестановке байтов, при которой прочитанный код порядка превратится в 0706050403020100 hex. А как быть с числами с плавающей запятой?
0
Fulcrum_013
1588 / 1071 / 124
Регистрация: 14.12.2014
Сообщений: 8,822
Завершенные тесты: 3
25.12.2014, 07:40 13
еще вариант - побитно сравниваешь начиная со старшего разряда две double -1 и 1. там где начинается несовпадение - начинается мантисса.
0
taras atavin
4204 / 1766 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
25.12.2014, 07:49  [ТС] 14
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
const double a=123.456; //и делаешь функцию: double MakeFloat(int IntegerPart, int DecimalPart, int PowerBits); //ну а дальше int PowerBits=1; while(MakeFloat(123,456,PowerBits++)!=a);
Что за фигня? Это всегда
C++
1
return ((double)123)+((double)456)/((double)1000);
, разрядности нет места, делитель считается целочисленным умножением в цикле на десять, то есть имеем:
C++
1
2
3
4
5
6
7
double MakeFloat(int IntegerPart, int DecimalPart, int PowerBits)
{
 int d;
 int t;
 for (d=1, t=DecimalPart; t!=0; d*=10, t/=10);
 return ((double)IntegerPart)+((double)DecimalPart)/((double)d);
}
.

Добавлено через 2 минуты
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
еще вариант - побитно сравниваешь начиная со старшего разряда две double -1 и 1. там где начинается несовпадение - начинается мантисса.
В IEEE 754 они различаются единственным битом знака числа, так как мантисса хранится в прямом коде.
0
Fulcrum_013
1588 / 1071 / 124
Регистрация: 14.12.2014
Сообщений: 8,822
Завершенные тесты: 3
25.12.2014, 07:51 15
Цитата Сообщение от taras atavin Посмотреть сообщение
А как быть с числами с плавающей запятой?
посчитать количество бит в мантиссе и порядке и записать к примеру char-ом. в один байт каждый они поместятся. Ну или интом, способ кодирования которого уже известен. А то что инт может выглядеть по разному связано с порядком байт в слове, и соответственно порядок аналогичный как для слова, так и для двойного слова и т.д. то есть - формат двойного слова (ну или четверного - для 16bit) - это формат не самого double а формат его упаковки в слове, который соответствует таковому у инта, и задача такой перепаковки решается указанным вами способом. А вот double надо после этой перепковки еще и приводить к формату по количеству бит показателя/мантиссы.

Добавлено через 1 минуту
Цитата Сообщение от taras atavin Посмотреть сообщение
double MakeFloat(int IntegerPart, int DecimalPart, int PowerBits)
{
*int d;
*int t;
*for (d=1, t=DecimalPart; t!=0; d*=10, t/=10);
*return ((double)IntegerPart)+((double)DecimalPart)/((double)d);
}
а теперь тоже самое только не используя double, а пользуясь битовым сдвигом
0
taras atavin
4204 / 1766 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
25.12.2014, 07:56  [ТС] 16
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
посчитать количество бит в мантиссе и порядке и записать к примеру char-ом. в один байт каждый они поместятся.
Поместятся то они конечно поместятся. А как записать?

Добавлено через 47 секунд
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
а теперь тоже самое только не используя double, а пользуясь битовым сдвигом
В целом? И получим 123 ровно.
0
Fulcrum_013
1588 / 1071 / 124
Регистрация: 14.12.2014
Сообщений: 8,822
Завершенные тесты: 3
25.12.2014, 08:04 17
Цитата Сообщение от taras atavin Посмотреть сообщение
В целом? И получим 123 ровно.
Нет, ты не понял. Формат представления double основан двух интах(размером не целое количество байт) - один мантисса, другой показатель. Собери double вручную (ну как эмулятор FPU собирает, только с заданным количеством бит)и сравни совпало ли с тем как собирается штатными средствами. Варианты перебери в цикле. Когда совпало - вариант представления известен.

Добавлено через 2 минуты
Цитата Сообщение от taras atavin Посмотреть сообщение
Поместятся то они конечно поместятся. А как записать?
А записать в той приладе которая генерит файл.
0
taras atavin
4204 / 1766 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
25.12.2014, 08:09  [ТС] 18
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Ну или интом, способ кодирования которого уже известен. А то что инт может выглядеть по разному связано с порядком байт в слове, и соответственно порядок аналогичный как для слова, так и для двойного слова и т.д.
Чёрта с два. Существует ещё смешанный порядок, то есть такой, при котором порядок байт в слове не совпадает с порядком слов в двойном слове, или двойных слов в четверном слове. В общем случае смешанного порядка порядок байт может даже не совпадать в разных словах одного двойного слова, или байты одного слова значения могут быть раскиданы по разным словам кода. В спецификации заявлена поддержка вообще всех возможных порядков байтов. Для слов это два порядка:
Номер байтаадрес
0&x
1((char*)&x)+1
и
Номер байтаадрес
0((char*)&x)+1
1&x
. Для двойных слов уже я насчитал уже 24 порядка.
0
Fulcrum_013
1588 / 1071 / 124
Регистрация: 14.12.2014
Сообщений: 8,822
Завершенные тесты: 3
25.12.2014, 08:16 19
Цитата Сообщение от taras atavin Посмотреть сообщение
Чёрта с два. Существует ещё смешанный порядок, то есть такой, при котором порядок байт в слове не совпадает с порядком слов в двойном слове, или двойных слов в четверном слове.
В любом случае double будет соответствоват 8-байтному (ну или сколько там в определенном таргете байт на double) инту. т.к. double кодируется уже внутри двойного/четверного слова. Соответственно перекодируешь слова/двойные/четверные/восьмерные или какие они там есть, а потом перекодируешь внутри них double. В любом случае формат записи т.е по какому адресу и какой длины значение должен быть известен заранее.
0
taras atavin
4204 / 1766 / 211
Регистрация: 24.11.2009
Сообщений: 27,565
25.12.2014, 08:26  [ТС] 20
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Ну или интом, способ кодирования которого уже известен. А то что инт может выглядеть по разному связано с порядком байт в слове, и соответственно порядок аналогичный как для слова, так и для двойного слова и т.д.
Чёрта с два. Существует ещё смешанный порядок, то есть такой, при котором порядок байт в слове не совпадает с порядком слов в двойном слове, или двойных слов в четверном слове. В общем случае смешанного порядка порядок байт может даже не совпадать в разных словах одного двойного слова, или байты одного слова значения могут быть раскиданы по разным словам кода. В спецификации заявлена поддержка вообще всех возможных порядков байтов. Для слов это два порядка:
Номер байтаадрес
0&x
1((char*)&x)+1
и
Номер байтаадрес
0((char*)&x)+1
1&x
. Для двойных слов я уже насчитал 24 порядка байт. Но это уже сделано. Любой порядок байтов в четверном слове однозначно кодируется таким четверным словом, что если на читающей машине порядок байт в четверном слове отличается, то оно будет искажено при чтении, чему оно должно быть равно известно из спецификации формата и любое другое четверное слово в файле подлежит такой перестановке байтов, при выполнении которой к четверному слову, кодирующему порядок байт в четверных словах будет устранено его искажение, вызванное не совпадением порядка байт в четверных словах. Так как порядок байт во всех четверных словах на одной машине одинаков, то такая перестановка восстанавливает значение любого искажённого не совпадением порядка четверного слова во всём файле.

Добавлено через 3 минуты
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
В любом случае double будет соответствоват 8-байтному (ну или сколько там в определенном таргете байт на double) инту. т.к. double кодируется уже внутри двойного/четверного слова. Соответственно перекодируешь слова/двойные/четверные/восьмерные или какие они там есть, а потом перекодируешь внутри них double.
Напоследок поучительная история. Когда я работал над тестовым проектом на GPU, у меня была последовательная и параллельная версия одной программы. Сравнив время выполнения, я был очень обрадован, так как получил ускорение в 300 раз. Но позже оказалось, что вычисления на GPU «разваливались» и обращались в NaN, а работа с ними в GPU была быстрее, чем с обычными числами. Интересно было другое — одна и та же программа на эмуляторе GPU (на CPU) выдавала корректный результат, а на самом GPU – нет. Позже оказалось, что проблема была в том, что этот GPU не поддерживал полностью стандарт IEEE754 и прямой подход не сработал.
http://habrahabr.ru/post/112953/.

Добавлено через 4 минуты
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Нет, ты не понял. Формат представления double основан двух интах(размером не целое количество байт) - один мантисса, другой показатель. Собери double вручную (ну как эмулятор FPU собирает, только с заданным количеством бит)и сравни совпало ли с тем как собирается штатными средствами. Варианты перебери в цикле. Когда совпало - вариант представления известен.
А если совпало случайно? И потом 456 тысячных уже не приводятся к двоичной дроби и ни какой сдвиг не поможет. То есть мантисса на самом деле не равна 123456 с каким бы то нибыло сдвигом.
0
25.12.2014, 08:26
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.12.2014, 08:26

Как вывести double в MessageBox'е?
Пробывал преобразовать в строковый: char buf; double time = clock () /...

Как избавиться от погрешности при выводе double?
После того, как считал строку &quot;3,2&quot;, перевожу во float, затем складываю с...

Как выводить в Edit тип данных Double ?
Всем доброго вечера. Написал программу формулу для расчета вот код программы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru