我试图围绕如何为游戏和渲染引擎编码数学函数的人们如何有效地使用优化的数学函数;让我进一步解释。
在这些领域中非常需要快速三角函数,有时您可以通过以仅对a有效的不同形式重写sin
,cos
或其他函数来优化它们。给定间隔,通常这意味着您的f(x)
近似值仅适用于第一象限,即0 <= x <= pi/2
。
现在f(x)
的输入仍然是所有4个象限,但实际公式仅涵盖该间隔的1/4,简单的解决方案是通过分析来检测象限输入并查看它属于哪个范围,如果输入来自不是第一象限的象限,则相应地调整公式的结果。
这在理论上是好的,但这也提出了一些非常糟糕的问题,特别是考虑到你正在做这一切以从你的CPU中偷走几个周期这一事实(你也得到了一致的实现,这不是平台依赖于英特尔x86 asm中的硬编码fsin
仅适用于x86且具有一定的误差范围,所有这些在其他平台上可能与其他asm指令不同),因此您应该保持并发和高速工作绩效水平。
我无法绕过&#34;切换案例&#34;象限解决方案是:
switch-case
置于实际计算f(x)
的相同函数中,可能通过实现公式来改善情况f(x)
在所述函数之外,但这将导致为任何给定的数学库维护的函数数量翻倍假设我可以在C或C ++中实现我的跨平台f(x)
,那么这个领域的程序员通常如何解决转换和映射输入的问题,通过实际实现的结果象限? / p>
答案 0 :(得分:2)
注意:在下面的回答中,我会非常一般地谈论代码。
假设我可以用C或C ++实现我的跨平台f(x),那么这个领域的程序员通常如何解决转换和映射输入的问题,通过实际实现将象限转换为结果?
对此的一般答案是:以最明显和最简单的方式实现您的目的。
我不完全确定我会遵循你的大多数论点/问题,但我有一种感觉,你正在寻找真正不存在的问题。您真的是否需要重新实现三角函数?不要陷入NIH的陷阱(不是在这里发明)。
直截了当 解决方案是检测象限
是的!我喜欢直截了当的代码。代码一目了然,它的作用非常明显。现在,有时候,有时候,你必须做一些疯狂的事情来让它做你想做的事情:性能,或避免你的控制之外的错误。但第一个版本应该是最明显和简单的代码,可以解决您的问题。从那里你进行测试,分析和基准测试,如果(仅当)你发现了性能或其他问题,那么你会进入疯狂的事情。
这在理论上是好的,但这也带来了一些非常糟糕的问题,
在大多数情况下,我会说理论和在实践中很好,我绝对不会看到任何&#34;坏&#34;问题。特定极端情况或设计要求中的次要问题最多。
您的一些具体评论中的一些内容:
cos()
的泰勒展开,看看对于大输入和小输入充分收敛需要多长时间。double
函数的memoization。想想在0和1之间有多少双打。现在在精度降低的情况下你可以利用它,但这很容易实现为针对这种情况量身定制的自定义功能。考虑到这一点,我并不完全确定如何为double
函数实现备忘,这实际上意味着什么,并且在此过程中不会失去准确性或性能。double
的值都不可能实现。如果只有52位正确,结果是什么?这将是一个很好的区域,可以进行一些测试,看看你得到了什么。我在C中使用了三角函数超过20年,99%的时间我只使用提供的内置函数。在极少数情况下,我需要通过测试或基准测试证明更多性能(或准确性),然后我才真正为自己的特定情况推出自己的自定义实现。我不会重写<math.h>
函数的全部内容,希望有一天我可能需要它们。
我建议尝试使用尽可能多的方法编写其中一些函数,并进行一些准确性和基准测试。这将为您提供一些实用知识,并为您提供有关您是否确实需要重新实现这些功能的一些硬数据。至少,这应该为您提供实施这些类型功能的实践经验,并且在此过程中有机会回答您的许多问题。