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