2009-11-09 2 views
3

Я пытаюсь решить загадку в тесте программирования.Извлечение чисел из 32-разрядного целого

Отказ от ответственности: Это тест на работу, но я не ищу ответа. Я просто ищу понимание того, как это сделать. Тест требует, чтобы я придумал набор решений для решения проблем в течение 2 недель, и в нем не указано, что я прихожу к решениям изолированно.

Итак, проблема:

У меня есть 32-битное число с битами расположены так:

siiiiiii iiiiiiii ifffffff ffffffff 

Где:

  • s является знаковый бит (1 = = отрицательный)
  • i - 16 целых битов
  • f - 15 бит фракции

Назначение - записать что-то, что декодирует 32-разрядное целое число в число с плавающей запятой. Учитывая следующие входы, он должен производить следующие результаты:

input   output 

0x00008000 1.0 
0x80008000 -1.0 
0x00010000 2.0 
0x80014000 -2.5 
0x000191eb 3.14 
0x00327eb8 100.99 

Я не имею никаких проблем получать знаковый бит или целую часть числа. Я получаю знаковый бит, как это:

boolean signed = ((value & (1 << 31)) != 0); 

Я получаю целую и дробную часть, как это:

int wholePart = ((value & 0x0FFFFFFF) >> 15); 

int fractionPart = ((value & 0x0000FFFF >> 1)); 

Часть У меня проблема с получают число в последних 15 бит для соответствия ожидаемым значениям. Вместо 3.14 я получаю 3.4587 и т. Д.

Если кто-то может дать мне подсказку о том, что я делаю неправильно, я был бы признателен. Больше всего на свете тот факт, что я не понял этого после нескольких часов беспорядка с ним, отчасти сводит меня с ума. :-)

+0

У вас возникла проблема с маской целиком, что тестовые данные не будут повторяться телятина. Двойные скобки в выражении fractionPart не совпадают с круглыми скобками в выражении wholePart; но я не вижу причины сдвинуть дробь в любом случае. Маска фракции также ошибочна. –

ответ

0
int wholePart = ((value & 0x7FFFFFFF) >> 15); 

int fractionPart = (value & 0x00007FFF); 

Key ваш бит-маска в калькулятор в двоичном режиме, а затем переверните его Hex ...

1

Посмотрите на то, что вы Андинг дробная часть с до сдвига ,

2

Несколько вещей ...

Почему бы не получить дробную часть как

int fractionPart = value & 0x00007FFF; // i.e. no shifting needed... 

Аналогично, нет смещения, необходимое для знака

boolean signed = ((value & (0x80000000) != 0); // signed is true when negative 

ответ знакомства Райана для эффективного использования дробной части , т. е. не воспринимать это буквально как значения цифр для десятичной части, а скорее ... некоторые из них связаны с af raction ...

4

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

+0

Ох. Я уволен ... –

+0

В 5 десятичных знаков, это правильно (и данные значения точно печатаются в 5 десятичных разрядах, как указано выше, с тремя дополнительными нулями). 15-битная фракция дает приблизительно 0,00003 (1/32K) за счет, поэтому 4 или 5 десятичных знаков являются разумными. –

0

сдвиг вправо 31 дает подписанную бит 1 = отр 0 = Pos

 
BEFORE siiiiiii iiiiiiii ifffffff ffffffff 
SHR 31 00000000 00000000 00000000 0000000s 

сдвиг влево 1 с последующим сдвигом вправо 16 дает вам Integer биты

 
BEFORE siiiiiii iiiiiiii ifffffff ffffffff 
SHL 1 iiiiiiii iiiiiiii ffffffff fffffff0 
SHR 16 00000000 00000000 iiiiiiii iiiiiiii 

сдвиг влево 17 с последующим Shift Right 15 дает для бит Faction

 
BEFORE siiiiiii iiiiiiii ifffffff ffffffff 
SHL 17 ffffffff fffffff0 00000000 00000000 
SHR 16 00000000 00000000 0fffffff ffffffff 

Смежные вопросы