Leave a comment

Comments 9

woodroof May 6 2012, 18:50:40 UTC
Ух ты, на erlang'е реально пишут, а не только рекламируют!

По теме.
0. Косячник.

1. Дописать единичку слева, остальное - дробная часть.

2. Видимо, первая, т.к. нет вызовов функций - просто работа с битами.

3. Модифицируя пример выше как-то так:

binary_to_double(<
F.
Там точно две правые скобки перед закрывающей обычной не нужны ( ... )

Reply

iash May 7 2012, 07:44:11 UTC
1. добавить слева один бит и разделить на 2^23 для float или на 2^52 для double ;)

2. почти. основная проблема второй функции - math:pow работает с float.
ее необходимо оптимизировать, заменив math:pow на битовые сдвиги.

3. так то да :) но хотелось увидеть алгоритм из binary_to_float1

закрывающие скобки нужны. + за внимательность :)

4. bingo!

5.
а) я специально опустил специальные случаи (0 и +/-infinity), чтобы не перегружать пост
в) не понял почему 254, по-моему 127.
г) если после перемножения полученное число больше 2^46 - добавить к экспоненте 1 и вычесть из результата перемножения 2^46.

6.
а) см 5а
в) нет необходимости сдвигать вправо, надо ли будет менять экспоненту лучше определять по результатам сложения мантисс, как в 5г.
д) первый вариант имеет еще одно преимущество - мы всегда работаем с unsigned. Во втором варианте всегда должно получаться положительное число, см пукт б
е) см 5г. и влево сдвигать точно не надо.

7. я не могу придумать алгоритм обращения мантиссы - не хватает математики :(

Reply

woodroof May 7 2012, 11:40:21 UTC
5в. да, мой косяк.
6е. хмм, 1+(-1/2), результат придётся сдвинуть на 1 _влево_ и учесть сдвиг в экспоненте.
7. Вот этот ряд быстро сходится к нужному числу:
X' = X * (1 + (1 - A*X) + (1 - A*X)^2), где X - начальное приближение или значение на предыдущем шаге, A - значение, к которому требуется посчитать обратное. A > 1, A < 2, X < 1, X > 0. Обратное к 1 получается 0.(9), что то же самое. Если в качестве начального приближения выбрать таблицу, в которой 16 бит будут верными (порядка 120 КиБ доп. данных), то алгоритм сходится за одну итерацию. С одним начальным приближением потребуется 2 или 3. Ну и там всякая пляска для с тем, что мы считаем число 2^32*X', не учитываем значимую единицу и всякое такое. Если интересно, могу кинуть полную реализацию.

Reply

woodroof May 7 2012, 11:49:48 UTC
Хмм, я ступил, это для фиксированной точки только в таком варианте канает, а для float несколько сложнее - не знаешь заранее, когда нужно остановиться, т.е. число итераций не фиксированное, и нужно учитывать текущую коррекцию. Ряд-то всё равно правильный, но реализация сложнее. Пожалуй, её предоставить сходу не смогу :)

Reply


woodroof May 6 2012, 19:29:25 UTC
А вот ещё вопрос: смутно помню, что когда-то бывает, что 0xABCD сохраняется как 0xBA 0xDC, только вот с размерностью не вспомню. Это в каких случаях бывает и как-либо затрагивает данный пример?

Reply

iash May 7 2012, 07:49:20 UTC
мне такой способ упаковки кажется несколько противоестественным.
если это 16-битное

если 32-битное, то всякие native endian (это архитектуро-зависимые способы упаковки) могут как угодно извращаться с байтами
при поиске решения для ерланга натыкался что 0x12345678 хранится как 0x56781234, по-моему в каком-то арме.
но тут менятся порядок байт, а не бит.

Reply

woodroof May 7 2012, 11:16:32 UTC
Ну да, я про байты и говорил. ABCD - это блоки.

Reply


Leave a comment

Up