很好奇这些是如何实现的。我看不出我会从哪里开始。它们是直接在float
/ double
位上工作吗?
另外在哪里可以找到math.h的函数源代码?我找到的只是带有原型的标题或带有从其他地方调用其他函数的函数的文件。
编辑:编辑标题后,部分信息丢失了。我特别指的是ceil()
和floor()
函数。
答案 0 :(得分:20)
如果您对查看此类算法的源代码感兴趣,那么fdlibm - 最初来自Sun的“Freely Distributable libm
”和Java数学库的参考实现 - 可能是一个好的开始。 (对于随意浏览,它肯定是一个比GNU libc更好的起点,其中的部分分散在各个子目录中 - math/
,sysdeps/ieee754/
等。
fdlibm假设它使用IEEE 754格式double
,如果你看一下实现 - 例如core of the implementation of log() - 你会看到他们使用各种聪明的技巧,通常使用标准double
算术的混合,以及double
的位表示的知识。
(如果您对支持基本IEEE 754浮点算法的算法感兴趣,例如可能用于没有硬件浮点支持的处理器,请查看John R. Hauser的SoftFloat。)< / p>
至于您的修改:通常,ceil()
和floor()
可能会在硬件中实现;例如,在x86上,GCC(启用了优化)使用frndint
指令生成代码,并适当摆弄FPU控制字以设置舍入模式。但是fdlibm的纯软件实现(s_ceil.c
,s_floor.c
)可以直接使用位表示。
答案 1 :(得分:6)
答案 2 :(得分:2)
加法和除法等数学函数几乎总是由机器指令实现。例外情况主要是小型处理器,如8048系列,它使用库来实现没有简单的机器指令序列来计算的函数。
sin()
,sqrt()
,log()
等数学函数几乎总是在运行时库中实现。一些罕见的CPU,比如Cray,有一个平方根指令。
告诉我们您正在使用哪种特定的实施方式(gcc,MSVC等,/ Mac,Linux等),有人会指引您准确地查看。
答案 3 :(得分:1)
在许多平台上(例如任何现代x86兼容的),许多数学函数都直接在浮点硬件中实现(参见例如http://en.wikipedia.org/wiki/X86_instruction_listings#x87_floating-point_instructions)。然而,并非所有这些都被使用(正如我在这里通过评论得到的其他答案)。但是,例如,sqrt
库函数通常直接根据SSE硬件指令实现。
有关基础算法如何工作的一些想法,您可以尝试阅读Numerical Recipes,它可以在某处以PDF格式提供。
答案 4 :(得分:1)
这些天很多都是在处理器上完成的。 我切开的芯片甚至没有乘法指令(z80)
我们必须使用Taylor Series.
的概念来估算内容大约在this page向下的1/2,你可以看到sin和cos是如何近似的。
答案 5 :(得分:0)
虽然现代CPU确实具有像sin,cos等常见的超频功能的硬件实现,但很少使用它。这可能是为了便携性,速度,准确性等......而是使用近似算法。