2014-12-26 1 views
1

Я реализую новый тип поплавка «NewFloat» в C, он использует 32 бита, он имеет без знака (только положительные числа Итак, все 32 бита используются экспонента или мантиссой.пользовательские поплавки с добавлением, реализующие математическое выражение - C

в моем примере, я 6bits для показателя (EXPBITS) и 26 для мантиссы (MANBITS). и мы это смещение, которое используется для представления отрицательных показателей степеней, который является (2^(EXPBITS-1) -1).

Учитывая значение NewFloat nf1, перевод в действительное число выполняется следующим образом: nf1 = 2^(экспоненты - смещение) * (1 + mantissa/2^MANBITS).

Теперь, учитывая два NewFloats (nf1, nf2), каждый с его (exp1, man1, exp2, man2 и то же смещение), Предполагая, что nf1> nf2, я могу вычислить экспоненту и мантиссу сумма обоих nf1 и НФ2, и это делается так: link

Чтобы сэкономить свое время, я обнаружил, что: Экспонента суммы является: exp1 Mantissa суммы является: man1 + 2^(exp2 - exp1 + MANBITS) + 2^(exp2 - exp1) * man2

Чтобы облегчить код, я разбиваю на работу и вычисляет отдельно каждый компонент t он мантисса: х = 2^(exp2 - exp1 + MANBITS) у = 2^(exp2 - exp1) * man2

Я вроде уверен, что я не осуществляет правильную мантиссу:

unsigned long long x = (1 << (exp2 - exp1 + MANBITS)); 
unsigned long long y = ((1 << exp2) >> exp1) * man2; 
unsigned long long tempMan = man1; 
tempMan += x + y; 

unsigned int exp = exp1;         // CAN USE DIRECTLY EXP1. 
unsigned int man = (unsigned int)tempMan; 

Сумма представлена ​​следующим образом: sum = 2^(exp1 - offset) * (1 + (man1 + x + y)/2^MANBITS).

Последнее, что мне нужно сделать, это случай переполнения мантиссы суммы. В этом случае я должен добавить 1 к экспоненте и разделить целое (1 + (man + x + y) 2^MANBITS) выражение.

В этом случае, учитывая, что мне нужно представлять только номинант в битах, как мне это сделать после деления?

Есть ли проблемы в моей реализации? У меня такое чувство.

Если у вас есть лучший способ сделать это, я был бы очень рад услышать об этом.

Пожалуйста, не спрашивайте меня, почему я это делаю. Это упражнение, которое я пытался решить более 10 часов.

+1

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

+1

Если вы получаете эту «рабочую», вы должны проверить условия угла * ad nauseam *, а также, предположительно, обычные задачи. Напишите тестовую программу, которая будет циклически перебирать действительные и недействительные данные, запускать ее за одну ночь, сравнивая результаты с хорошо обоснованной реализацией. –

ответ

3

Код делает signed int смены и, конечно, unsigned long long.

// unsigned long long x = (1 << (exp2 - exp1 + MANBITS)); 
    unsigned long long x = (1LLU << (exp2 - exp1 + MANBITS)); 

Примечание:

Предлагайте более осмысленные имена переменных, как x_mantissa.

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

Переполнение не обнаружено/выполнено.

Субстандарты не реализованы. Если NewFloat не использовать их, не то, что a-b --> 0 не означает a == b.

+0

Xcode не знает «LUU», но «LLU», и я думаю, это то, что вы имели в виду. Хм, это не помогло мне решить проблему, и я не понимаю, зачем это нужно ... До тех пор, пока я оставляю смены, почему я должен заботиться о типе (подписанный или неподписанный)? Я должен использовать неподписанные, если я хочу нажать 0 при правильном переключении, не так ли? Спасибо за ваши комментарии. – johni

+0

@johni Предположим, что 'int' является 32-битным. Выполнение '1 << 48' смещает' int' больше его ширины, что является неопределенным поведением (UB). Типичным результатом является то, что используются только наименее значимые 5 бит из 48, и возникает результат «1 << 16». Используя '1LLU', код смещает' unsigned long long' (не менее 64-битного типа). – chux

+0

@johni Что касается подписанных или беззнаковых целых чисел: код формирует предвзятую мантиссу как результат беззнакового целого. Разумеется, менее запутанным для других, если код использует неподписанный тип, а не подписанный тип, чтобы представлять неподписанную предвзятую мантиссу. – chux