问题描述
我不是C ++(/ C)的专家,但也不是一个完整的初学者。
我正在写一个更快的cos(和sin)近似基于
预先计算的数据(取得了一定的成功)当我发现从双倍到整数时,
非常昂贵,所以可能是cos / sin近似值
没有预先计算会更好(更快)。
尽管如此我仍然需要找出装置上的位置 -
角度
(从0到2PI的双倍(v))是。我找了一个像
这样的命令
int not_negative(double d)//如果d ==(+)0.0则返回1,d == 1.2 aso else 0
(和int not_positive(double d)//返回1如果d == - 0.0 d == - 1.6(否则
0))
我的猜测是这样一个命令可以快速实现(有些
比特错误 - 我在这里错了吗?)我不知道dobbles看起来怎么样?
比特
如果它在所有机器上都是一样的,但我认为可以快速制作
....
如果我有一个像这样的快速命令(并且gcc / g ++与-O3不会使
比较x> = 0快 - 也许答案就是那个是真正的
问题
,但如果可以在不进行比较的情况下制作快速功能,那么
语言就会发出信号比较,因此
更快)
可以编写如下内容:
取决于函数的速度是的可能他比一个
二进制文件更快
搜索v。
有没有人对此有任何意见?
双cos(双v)
{
:重新运行
v = fabs(v) - (2.0 * PI);
int part = 0;
part = part + not_negative(v); // v大于2PI
v = v + PI / 4.0;
part = part + not_negative(v);
v = v + PI / 4.0;
part = part + not_negative(v);
v = v + PI / 4.0;
part = part + not_negative( v);
v = v + PI / 4.0;
part = part + not_negative(v);
v = v + PI / 4.0;
part = part + not_negative(v);
v = v + PI / 4.0;
part = part + not_negative(v);
v = v + PI / 4.0;
part = part + not_negative(v);
开关(部分)
{
案例0:为case0返回一些内容;
案例1:为case1返回一些内容;
案例2:返回适用于case2;
案例3:为case3返回一些内容;
案例4:为case4返回一些内容;
案例5:返回一些内容case5;
案例6:为case6返回一些内容;
案例7:为case7返回一些内容;
案例8:x不在[ 0; 2PI]。
//这不是部分这笔交易但是
//修复x并转到goto重新运行
}
}
I am not an expert on C++(/C), but also not a complete beginner.
I was writing a faster cos (and sin) approximation based on
precalculated data (with some success) when I discovered that going
from double to int is quite expensive, so maybe a cos/sin approximation
without precalculation would be better (faster).
Nevertheless I (still) needed to find out where on the unit-cirkle the
angle
(a double (v) from 0 to 2PI) was. And I looked for a command like
int not_negative(double d) // return 1 if d==(+)0.0, d==1.2 aso else 0
(and int not_positive(double d) // return 1 if d==-0.0 d==-1.6 (else
0))
My guess is that such a command could be made real fast (with some
bit-mangleling - am I wrong here?) I do not know how dobbles looks in
bits
and if it is the same on all machines, but I think it could be made
fast ....
If I had a fast command like this (and gcc/g++ with -O3 does not make
the
comparison x>=0 fast - maybe the answer is that that is the real
problem
,but if it is possible to make a fast function without a compare the
language would signal that this works without a compare and therefore
is faster)
it would be possible to write something like :
Depending on how fast the function is this might he faster than a
binary
search on v.
Does anybody has some comments on this ?
double cos(double v)
{
:rerun
v=fabs(v)-(2.0*PI);
int part = 0;
part=part + not_negative(v); // v was bigger than 2PI
v=v+PI/4.0;
part=part + not_negative(v);
v=v+PI/4.0;
part=part + not_negative(v);
v=v+PI/4.0;
part=part + not_negative(v);
v=v+PI/4.0;
part=part + not_negative(v);
v=v+PI/4.0;
part=part + not_negative(v);
v=v+PI/4.0;
part=part + not_negative(v);
v=v+PI/4.0;
part=part + not_negative(v);
switch (part)
{
case 0 : return something for case0;
case 1 : return something for case1;
case 2 : return something for case2;
case 3 : return something for case3;
case 4 : return something for case4;
case 5 : return something for case5;
case 6 : return something for case6;
case 7 : return something for case7;
case 8 : x is not in [0;2PI].
// This was not a "part" of the deal but
// fix x and goto rerun
}
}
推荐答案
解决方案不可移植。但是,无论如何,看一下你的双重格式的b / b
编译器实现细节,它将是由指数和尾数组成的
,在尾数中找到符号位,
使非便携式实现依赖于小心方法
来测试它。
准备将其更改为当你发现更好的方法时(比如
分区来发现PI / 4.0包含多少倍)
Zara
The solution would not be portable. But, anyhow, take a look at your
compiler implementation details about the double format, which will be
formed by exponent and mantissa, locate the sign bit in the mantissa,
make a non-portable implementation dependent be-careful-with-it method
to test it.
An be ready to change it as soon as you discover better ways (such as
division to discover how many times PI/4.0 is contained in a double)
Zara
感谢您的回答 - 我的猜测是它不便携。
(我想编写可移植的C ++(或者在这种情况下它只是C)
我的主题也是:C ++中的sign_command missing(?) ;因此
编译器可能知道如何快速为给定平台做这件事,
但我不能做出快速算法,除非我编写创建C ++的C ++
(我不喜欢。)
PS:我应该先写的东西:
int part = st atic_cast< INT> (楼层(v *(1 /(2.0 * PI)* 8)));
不是(我记得它)表现良好。演员和地板都很昂贵。我考虑不使用2
原因的预先计算数据。
1)查找可能的缓存未命中
2)演员来自double to int
Thanks for the answer - It was my guess that it would not be portable.
(And I want to write portable C++ (or in this case it is just C)
My subject was also : "sign_command missing(?) in C++" hence the
compiler would probably know how to do this quick for a given platform,
but I can make no fast algoritm unless I write C++ that creates C++
(Which I am not fond of.)
PS : Something I should have written first :
int part = static_cast<int> (floor(v*(1/(2.0*PI)*8)));
is not (as I remember it) performing good. Both the cast and floor are
expensive. I was considering not using pre_calculated data of 2
reasons.
1) The lookup with a possible cache-miss
2) The cast from double to int
这个是次优的,实际上是多余的。 *如果您保证
v> = 0.0,则以下表达式就足够了:
int part = static_cast< int> (v *(1 /(2.0 * PI)* 8));
因为将实体类型转换为整数类型,所以将
向零舍入。
This one is sub-optimal, it is in fact redundant. *IF* you guarantee
that v >=0.0, then the following expression is enough:
int part = static_cast<int> (v*(1/(2.0*PI)*8));
Because casting form real types to integer types is done rounding
towards zero.
这篇关于C ++中的sign_command(例如not_negative)缺少(?)(/ C)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!