Как получить знак, мантисса и показатель числа с плавающей запятой

У меня есть программа, которая работает на двух процессорах, одна из которых не поддерживает поддержку с плавающей запятой. Поэтому мне нужно выполнить вычисления с плавающей запятой, используя фиксированную точку в этом процессоре. Для этой цели я буду использовать библиотеку эмуляции с плавающей запятой.

Мне нужно сначала извлечь знаки, мантиссы и показатели чисел с плавающей запятой на процессоре, которые поддерживают плавающую точку. Итак, мой вопрос заключается в том, как я могу получить знак, мантисса и показатель числа чисел с плавающей точкой с одной точностью.

Следуя формату этого рисунка,

введите описание изображения здесь Это то, что я сделал до сих пор, но кроме знака, ни мантисса, ни экспоненты верны. Я думаю, что я что-то упускаю.

void getSME( int& s, int& m, int& e, float number ) { unsigned int* ptr = (unsigned int*)&number; s = *ptr >> 31; e = *ptr & 0x7f800000; e >>= 23; m = *ptr & 0x007fffff; } 

Я думаю, что лучше использовать союзы для выполнения бросков, это яснее.

 #include  typedef union { float f; struct { unsigned int mantisa : 23; unsigned int exponent : 8; unsigned int sign : 1; } parts; } float_cast; int main(void) { float_cast d1 = { .f = 0.15625 }; printf("sign = %x\n", d1.parts.sign); printf("exponent = %x\n", d1.parts.exponent); printf("mantisa = %x\n", d1.parts.mantisa); } 

Пример, основанный на http://en.wikipedia.org/wiki/Single_precision

Узнайте формат чисел с плавающей запятой, используемых в ЦП, которые напрямую поддерживают плавающие точки и разбивают их на эти части. Наиболее распространенный формат – IEEE-754 .

В качестве альтернативы вы можете получить эти части с помощью нескольких специальных функций ( double frexp(double value, int *exp); и double ldexp(double x, int exp); ), как показано в этом ответе .

Другой вариант – использовать %a с printf() .

Мой совет – придерживаться правила 0, а не повторять, что уже делают стандартные библиотеки, если этого достаточно. Посмотрите на math.h (cmath в стандартном C ++) и функции frexp, frexpf, frexpl, которые разбивают значение с плавающей запятой (double, float или long double) в своей значимой и экспоненциальной части. Чтобы извлечь знак из знака, вы можете использовать signbit, также в math.h / cmath или copysign (только C ++ 11). Некоторые альтернативы с более легкой семантикой – modf и ilogb / scalbn, доступные в C ++ 11; http://en.cppreference.com/w/cpp/numeric/math/logb сравнивает их, но я не нашел в документации, как все эти функции ведут себя с +/- inf и NaN. Наконец, если вы действительно хотите использовать битмаски (например, вам отчаянно нужно знать точные биты, и ваша программа может иметь разные NaN с разными представлениями, и вы не доверяете вышеуказанным функциям), по крайней мере, сделать все независимым от платформы используя macros в float.h / cfloat.

Вы ошибаетесь. Я думаю, вы хотите:

 s = *ptr >> 31; e = *ptr & 0x7f800000; e >>= 23; m = *ptr & 0x007fffff; 

Помните, когда вы & , вы обнуляете биты, которые вы не устанавливаете. Таким образом, в этом случае вы хотите обнулить знаковый бит, когда вы получите экспонента, и вы хотите обнулить знаковый бит и экспонента, когда получите мантиссу.

Обратите внимание, что маски появляются непосредственно из вашего изображения. Итак, маска экспоненты будет выглядеть так:

0 11111111 00000000000000000000000

и мантиссовая маска будет выглядеть так:

0 00000000 11111111111111111111111

На Linux- #include glibc-заголовки предоставляют заголовок #include с определениями типов с плавающей точкой, например:

 union ieee754_double { double d; /* This is the IEEE 754 double-precision format. */ struct { #if __BYTE_ORDER == __BIG_ENDIAN unsigned int negative:1; unsigned int exponent:11; /* Together these comprise the mantissa. */ unsigned int mantissa0:20; unsigned int mantissa1:32; #endif /* Big endian. */ #if __BYTE_ORDER == __LITTLE_ENDIAN # if __FLOAT_WORD_ORDER == __BIG_ENDIAN unsigned int mantissa0:20; unsigned int exponent:11; unsigned int negative:1; unsigned int mantissa1:32; # else /* Together these comprise the mantissa. */ unsigned int mantissa1:32; unsigned int mantissa0:20; unsigned int exponent:11; unsigned int negative:1; # endif #endif /* Little endian. */ } ieee; /* This format makes it easier to see if a NaN is a signalling NaN. */ struct { #if __BYTE_ORDER == __BIG_ENDIAN unsigned int negative:1; unsigned int exponent:11; unsigned int quiet_nan:1; /* Together these comprise the mantissa. */ unsigned int mantissa0:19; unsigned int mantissa1:32; #else # if __FLOAT_WORD_ORDER == __BIG_ENDIAN unsigned int mantissa0:19; unsigned int quiet_nan:1; unsigned int exponent:11; unsigned int negative:1; unsigned int mantissa1:32; # else /* Together these comprise the mantissa. */ unsigned int mantissa1:32; unsigned int mantissa0:19; unsigned int quiet_nan:1; unsigned int exponent:11; unsigned int negative:1; # endif #endif } ieee_nan; }; #define IEEE754_DOUBLE_BIAS 0x3ff /* Added to exponent. */ 

Поместите указатель на переменную с плавающей точкой как нечто вроде unsigned int . Затем вы можете сдвигать и маскировать биты, чтобы получить каждый компонент.

 float foo; unsigned int ival, mantissa, exponent, sign; foo = -21.4f; ival = *((unsigned int *)&foo); mantissa = ( ival & 0x7FFFFF); ival = ival >> 23; exponent = ( ival & 0xFF ); ival = ival >> 8; sign = ( ival & 0x01 ); 

Очевидно, вы, вероятно, не использовали бы неподписанные ints для экспоненты и битов знака, но это должно по крайней мере дать вам эту идею.

  • Симулятор или эмулятор? В чем разница?
  • Android: Имитировать Wi-Fi в эмуляторе?
  • Список устройств поддержки HCE?
  • AVD - PANIC: Не удалось открыть ... - не проблема
  • Android - Сохранить изображение с URL на SD-карту
  • Как подключить эмулятор Android к ADB?
  • Interesting Posts

    В C99, f () + g () не определено или просто неопределено?

    Как добавить загрузчик даты Picker Bootstrap 3 в проекте MVC 5 с использованием механизма Razor?

    Лучший Linux для одного приложения и быстрая загрузка? (Также How-to?)

    Emacs: удаление пробелов или слово

    Windows Forms: Как скрыть кнопку Close (x)?

    Статический и нестатический объект блокировки в синхронизированном блоке

    Разница между функциями $ (window) .load () и $ (document) .ready ()

    Простой экспорт и импорт базы данных SQLite на Android

    получить уникальный идентификатор машины

    Как ограничить скорость передачи данных в сети Windows?

    Поддерживает ли Intel интегрированную графику масштабирование ближайшего соседа?

    У меня случайно есть BSOD, восстановление ПК заставит его работать?

    Ширина и высота canvasа в HTML5

    Mysql объединяет запрос для нескольких «тегов» (отношения «многие ко многим»), которые соответствуют всем тегам?

    Извлечение текста извещных, contentView или contentIntent

    Давайте будем гением компьютера.