Реализация ceil() и floor()
Просто любопытно, как это реализовано. Я не вижу, с чего бы начать. Работают ли они непосредственно на float
"S /double
биты?
Также, где я могу найти исходный код функций из math.h? Все, что я нахожу, это либо заголовки с прототипами, либо файлы с функциями, которые вызывают другие функции откуда-то еще.
EDIT: часть сообщения была потеряна после редактирования заголовка. В частности, я имел в виду ceil()
а также floor()
функции.
6 ответов
Если вам интересно посмотреть исходный код алгоритмов для такого рода вещей, тогда fdlibm - "Свободно распространяемый" libm
"Первоначально от Sun и эталонной реализации для математических библиотек Java - может быть хорошим местом для начала. (Для случайного просмотра, это, безусловно, лучшее место для начала, чем GNU libc, где части разбросаны по разным подкаталогам - math/
, sysdeps/ieee754/
, так далее.)
fdlibm предполагает, что работает с форматом IEEE 754 double
и если вы посмотрите на реализации - например, ядро реализации log () - вы увидите, что они используют все виды хитрых трюков, часто используя смесь обоих стандартных double
арифметика и знание битового представления double
,
(И если вас интересуют алгоритмы для поддержки базовой арифметики IEEE 754 с плавающей запятой, например, которые могут использоваться для процессоров без аппаратной поддержки с плавающей запятой, взгляните на SoftFloat Джона Р. Хаузера.)
Что касается вашего редактирования: в общем, ceil()
а также floor()
вполне может быть реализовано аппаратно; например, на x86 GCC (с включенной оптимизацией) генерирует код, используя frndint
инструкция с соответствующим переключением управляющего слова FPU для установки режима округления. Но чистые программные реализации fdlibm (s_ceil.c
, s_floor.c
) делать работу с использованием битового представления напрямую.
math.h является частью стандартной библиотеки C.
Если вас интересует исходный код, библиотека GNU C (glibc) доступна для проверки.
РЕДАКТИРОВАТЬ ДОБАВИТЬ:
Как уже говорили другие, математические функции обычно реализуются на аппаратном уровне.
Математические функции, такие как сложение и деление, почти всегда реализуются машинными инструкциями. Исключение составляют в основном небольшие процессоры, такие как семейство 8048, которые используют библиотеку для реализации функций, для которых не существует простой последовательности машинных инструкций для вычисления.
Математические функции, такие как sin()
, sqrt()
, log()
и т. д. почти всегда реализуются в библиотеке времени выполнения. У нескольких редких процессоров, таких как Cray, есть инструкция квадратного корня.
Скажите нам, какую конкретную реализацию (gcc, MSVC и т. Д./Mac, Linux и т. Д.) Вы используете, и кто-то точно подскажет вам, где искать.
Многое сделано на процессорах в наши дни. У чипа, на котором я резал зубы, даже не было инструкции умножения (z80)
Мы должны были приблизить вещи, используя концепцию серии Тейлора.
Примерно на половине пути вниз по этой странице вы можете увидеть, как аппроксимируются грех и cos.
На многих платформах (таких как любая современная x86-совместимая) многие математические функции реализуются непосредственно в аппаратном обеспечении с плавающей запятой (см., Например, http://en.wikipedia.org/wiki/X86_instruction_listings). Однако не все они используются (как я узнал из комментариев к другим ответам здесь). Но, например, sqrt
Функция библиотеки часто реализуется непосредственно в терминах аппаратных инструкций SSE.
Для некоторых идей о том, как работают лежащие в основе алгоритмы, вы можете попробовать прочитать Числовые рецепты, которые доступны где-нибудь в формате PDF.
В то время как современные CPU имеют аппаратную реализацию общих трансцендентных функций, таких как sin, cos и т. Д., Они редко используются как есть. Это может быть связано с переносимостью, скоростью, точностью и т. Д. Вместо этого используются алгоритмы аппроксимации.