Реализация ceil () и пола ()

Просто любопытно, как они реализованы. Я не вижу, с чего начать. Они работают непосредственно на битах 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 и т. Д., Он редко используется как есть. Это может быть причина портативности, скорость, точность и т. Д. Вместо этого используются алгоритмы аппроксимации.