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