2015-09-30 2 views
0

У меня есть часть части с поплавком (например, 5 из -10.5). Это символ, потому что я извлек его из ввода. Как я могу преобразовать этот символ в двоичную дробную часть этого числа с плавающей запятой? (Я строю поплавковый ввод -> вывод HEX в 32-битном IEEE784, я уже извлечил двоичные представления знака, экспоненты и целочисленную часть мантиссы.)Преобразование фракционной части в двоичную.

Я думал о реализации алгоритма умножения фракции на два и взятие остатка, затем повторение до заполнения мантиссы, но мне не разрешено использовать какие-либо операции с плавающей запятой в задании.

Примеры: Входы пользователя -10.5. Программа должна принять долю числа (которая равна 5) и преобразовать ее в двоичный формат (который равен 1 (.1))

EDIT: Я ограничен размером в 16 бит, поэтому мне нужно решение для работают с числами> 2^16-1.

+2

Вопрос не очень ясен. Пожалуйста, покажите некоторые типичные данные, как они получены, и требуемый результат в каждом случае. И код («Я извлек ...») –

+0

На данный момент у меня есть два 32-битных слова памяти, длинные номера типов, один - 1 (из-за знака отрицательный), а другой - 10 в двоичном формате. У меня также есть массив символов с символом «5» как первый и единственный элемент. Это доля предоставленного числа (это может быть «05», «00001257852» и т. Д.). Мне просто нужно преобразовать его в биты. –

+1

... в вопросе, нет как вафли пожалуйста. –

ответ

5

Вы в принципе имеете правильную идею. Просто удвойте десятичную часть, и перенос станет числом. Давайте попробуем преобразовать .7 в двоичную в качестве примера (.5 слишком просто)

NUMBER REMAINDER CARRY 
    .7  ---  . 
    1.4  .4  1 
    .8  .8  0 
    1.6  .6  1 
    1.2  .2  1 
    .4  .4  0 
    .8  .8  0 
    1.6  .6  1 
    1.2  .2  1 
&ct. 

.7 Так в двоичном виде .101100110.... 10.7 бы просто 1010.101100110...

Вы можете остановить преобразования в двоичный когда остаток становится 0, или когда-то общее представление становится 24 бит долго из-за пределы IEEE точности с плавающей точкой.

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

NUMBER  %10 /10 
    7  ---  . 
    14  4  1 
    8  8  0 
    16  6  1 
    12  2  1 
    4  4  0 
    8  8  0 
    16  6  1 
    12  2  1 
&ct. 

В случае .07 вы представляете остаток и нести %100 и /100 соответственно. В случае .007 вы использовали бы %1000 и /1000.

+0

Большое вам спасибо! Я постараюсь реализовать решение сразу, великолепно! –

2

В смысле IEEE-754 нет четкого значения для дробной части числа с плавающей запятой вне контекста общего числа. Биты, которые отличают значение 10.5 от значения 10.0, являются меньшим подмножеством общего представления, чем биты, которые отличают значение 0.0 от значения 0.5. Когда мы говорим о «фракционной» части цифрового представления IEEE-754, обычно говорят о всех битах мантиссы; для бинарного формата с двойной точностью IEEE 754, который составляет 24 бита, включая один подразумеваемый бит, независимо от величины числа.

UPDATE/ПЕРЕСМОТР:

на основе обновлений, разъясняющие этот вопрос, я заменил большую часть моего предыдущего ответа, в котором рассматриваются проблемы программно извлечения битов float или double, в отличие от преобразования десятичный формат текст представление в биты представления формата IEEE-754. Анализ текста - сложная проблема, как я уже сказал в оригинальной версии этого ответа.

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

Вот реальный подход к общей проблеме:

  1. Определить знак числа входных на основе наличия или отсутствия отрицательного знака.

  2. Формируйте представление бинума абсолютного значения входного номера. Например, представление base-1,000,000,000, хранящееся в массиве uint32_t. Пока база имеет мощность 10, в этом представлении просто проанализировать введенный номер десятичного формата, и при этом не возникает ошибки округления.

  3. Масштабирования bignum представления соответствующей степень два, чтобы получить уменьшенную величину от 2 и 2 - 1. Это может быть сделано только с целочисленной арифметикой. Обратите внимание, что возможно, вам придется масштабировать до вместо того, чтобы подняться вверх. В любом случае это масштабирование может выполняться только с помощью целочисленной арифметики. Помните, какая сила двух (s) использовалась как масштабный коэффициент (то есть логарифм базы-2 масштабного коэффициента, не столько сам масштабный коэффициент, это может легко выйти из алгоритма без вычисления необходимых трансцендентных функций) ,

  4. Точность округления до единицы.

Вы затем знаковый бит с шагом 1, биты мантиссы/мантиссы как остальные старшие биты bignum (помните, что наиболее значимым из них является неявной, не явно, в окончательном IEEE формат), а экспонент - 23 - s.

Обратите внимание, что этот подход может быть продлен очень естественно до научной нотации.

+0

К сожалению, некоторым профессорам университетов просто не хватает здравого смысла. Моя идея, предложенная парнем из моего университета, который уже занимался этой задачей, переводил целые и дробные части отдельно (вот что я делаю). Я положу их на 32-битные слова памяти (знаковое слово, слово экспонента, слово мантиссы), сдвиг, если необходимо, и добавьте в регистр. Тогда я все распечатаю. –

+0

Ну, помните, что 32 бита могут быть недостаточными. Вам может потребоваться всего лишь ноль или целых 53 (для двойной двойной точности IEEE), чтобы представить часть величины числа, которая превышает единицу точности. Также обратите внимание на правильное округление результата для чисел, которые не являются точно представленными. –

+0

Я понимаю, но мне все равно, что нужно округлить и т. Д. Мне просто нужно добавить столько цифр в 23 бит мантиссы (это не слово памяти, а часть слова), пока оно не станет полным. –

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