[Упражнение 0003] Изучаем алгоритмы

Опубликовал – 30.09.2010

Новая задачка, товарищи. Проанализируйте код и назовите имя ф-ции.

inline float xxx(float x)
{
	float retval;

	__asm {
		mov		eax, x
		sub		eax, 0x3F800000
		sar		eax, 1
		add		eax, 0x3F800000
		mov		[retval], eax
	};

	return retval;
}

Незабываем прокомментировать свой ответ. Вопрос скорей на знание алгоритма, нежели языка.

P.S. Этот кусок кода я взял из исходников quake 2.

Рассказать друзьям:
  • Добавить ВКонтакте заметку об этой странице
  • Мой Мир
  • Facebook
  • Twitter
  • Яндекс.Закладки
  • В Живую Ленту Google
  • Сто закладок
Комментарии (11) - [Упражнение 0003] Изучаем алгоритмы

Ответ

  1. xrnd:

    Интересные у вас упражнения, но для меня наверно слишком простые :)

    Я пишу свой учебник по ассемблеру (http://asmworld.ru/uchebnik/)
    На ваш сайт попал случайно, заметив ссылку на мой справочник команд.

    Thumb up Thumb down 0

  2. xrnd:

    Вообще, странная функция :)
    Она по-разному будет работать для разных чисел.

    Я так понимаю, её предполагалось вызывать только для 1 < x < 2

    Thumb up Thumb down 0

    • нет. условия там скорей 0 < x; Ф-ция будет работать везде одинаково.. исследуем алгоритм дальше ;)

      • xrnd:

        Ааа. Я кажется понял. Но этот алгоритм мне не нравится – плохая точность вычислений. Для 1 < x < 2 он просто делит на 2 дробную часть числа.

        Не лучше ли использовать сопроцессор или команды MMX, SSE? Возможно, на современных процессорах этот алгоритм – не самый быстрый.

        Thumb up Thumb down 0

        • Погрешность алгоритма окупается сполна его скоростью работы! Как же все таки называется эта ф-ция?

          • xrnd:

            Для игр, наверно, точности хватит :)
            Извлечение квадратного корня – sqrt.

            Вычитание числа 0×3F800000 – это смещение экспоненты числа. Затем арифметический сдвиг вправо делит мантиссу и экспоненту на 2. Причём, если экспонента нечетная, то к мантиссе прибавляется 1/2. После чего смещение прибавляется к экспоненте.

            x = (1+m)*2^e, где m – мантисса, e – экспонента.

            Для четной экспоненты (младший бит равен 0):
            retval = (1+m/2)*2^(e/2)

            Для нечетной экспоненты (младший бит равен 1):
            retval = (1+(1+m)/2)*2((e-1)/2)

            Интересно протестировать, на сколько это быстрее сопроцессора.

            Well-loved. Like or Dislike: Thumb up Thumb down +7

          • xrnd:

            Если 1 < x < 2, то алгорит просто делит дробную часть числа на 2.

            Thumb up Thumb down 0

            • В играх такой точности не понадобится. Я использую эту формулу уже много лет) По скорости она в несколько раз превосходит sqrt(..); Нужно будет на досуге выстроить график значений, если займусь, обязательно выложу результат:)

Ответить

Comments

Перед отправкой формы: