Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Работа с битовыми полями


Автор: Nikole 12.9.2005, 00:18
Как в С++ получить из битовых полей объединения беззнаковых
литер (unsigned char) значение переменной типа float,
если извесен порядок следования полей (элементов искомого
числа): мантисса M, знак мантиссы (0-положит, 1-отрицат),
знак порядка, порядок N, а также известно количество бит,
отводимое для хранения мантиссы (KBM) и для хранения порядка (KBP).
Например, если KBM=2, KBP=3, то набор бит 11 0 1 110 (битовые
поля разделены пробелами) должен дать число +3*10^(-6)=3/1000000.
Нужна высокая скорость выполнения операций, поэтому функции POW и др.
подобные использовать не желательно.

Автор: Дрон 12.9.2005, 00:35
Фигасе...

Раза с 5-го понял что требуется. А вот что дано всё равно не понимаю smile

Цитата(Nikole @ 12.9.2005, 01:18)
битовых полей объединения беззнаковых литер

И что это такое? Как-то я такое и представить не могу. Битовые поля знаю. Объединения знаю. "Беззнаковые литеры" тоже знаю. Но чтобы всё вместе...

Цитата(Nikole @ 12.9.2005, 01:18)
а также известно количество бит,
отводимое для хранения мантиссы (KBM) и для хранения порядка (KBP).

Оно фиксированно или задаётся переменными?

Цитата(Nikole @ 12.9.2005, 01:18)
Нужна высокая скорость выполнения операций, поэтому функции POW и др.
подобные использовать не желательно.

Кому нужна?
Если это студенческая лабораточная работа, то это одно дело. Если же это реальная задача, то хоть скажите на каком процессоре это всё делается -- может проще будет асм использовать?
Добавлено @ 00:39
В догонку.

Цитата(Nikole @ 12.9.2005, 01:18)
должен дать число +3*10^(-6)=3/1000000.

Используются степени 10-ки? Со степенями 2-ки было бы гораздо проще.

Автор: Mayk 12.9.2005, 07:57
Если честно, то до конца не врубился что требуется(но в отличии от Дрона прочитал 3 раза).
Я понял задачу так - есть число очень дикого формата и нам его надо преобразовать в юзабельный флоат.

Цитата(Nikole @ 12.9.2005, 04:18)
Нужна высокая скорость выполнения операций, поэтому функции POW и др.
подобные использовать не желательно.

Не получится без pow. Если не отказаться от десятичной СС.

Итак. Для начала восстановим экспоненту(ака порядок). Будем считать, что мы восстанавливаем float. Хотя лучше бы long double, ну да ладно. Не помню есть ли для него pow.
Код

int exp = getExponentFromUnion(UNION);  // <-- биты экспоненты из объединения
if(getExponentSign(UNION)) // <-- восстанавливаем знак
 exp=-exp; // если нужно, экспонента стала отрицательной

//делаем число
float rs = getMantiss(UNION) * pow(10, exp); 
(*(uint32_t*)(&rs)) |= getMantissSign() << 31; //восстанавливаем знак числа


Вроде должно работать. Но не проверял.


Цитата
Оно фиксированно или задаётся переменными?

Оно фиксированно хотя бы IEEE754. Никаким бубном в float нельзя будет запихнуть Float.MAX_VALUE+1.

Цитата
Со степенями 2-ки было бы гораздо проще.

Помимо того что было бы проще, при преобразовании из 2-ного формата Дикого Флоата в IEEE'овский флоат не терялась бы точность. Ведь 0,3 нельзя представить в двоичном формате.

Цитата

Используются степени 10-ки?

Безумный Флоат. Более диким был лишь Безумный Синглтон smile

Автор: bilbobagginz 14.9.2005, 08:06
мне очень понравился ваш анализ... интересно что обо всём этом думает сам Nicole
smile smile smile smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)