## RE: [Algorithms] Fast simultaneous Sin() and Cos()

 RE: [Algorithms] Fast simultaneous Sin() and Cos() From: Jason Dorie - 2001-03-14 21:30:32 ``` You're probably quite right, but I rearranged the code to do exactly that and got identical results. I'm guessing the compiler optimized it that way for me, so I changed the code back for readability. I am also aware that it is a taylor series, and that it only approximates the sin/cos functions in the range of +/- PI/2, which is why I have the range check / adjust code in the beginning. Jason -----Original Message----- From: gdalgorithms-list-admin@... [mailto:gdalgorithms-list-admin@...]On Behalf Of David Hunt Sent: Wednesday, March 14, 2001 12:25 PM To: gdalgorithms-list@... Subject: Re: [Algorithms] Fast simultaneous Sin() and Cos() Surely all those ang*ang*angs are better done in steps. Ie float ang1=ang; *pSin=ang; ang*=ang1; // now squared *pCos=1.0f-ang/2; ang*=ang1; // now cubed *pSin-=ang*(1.0f/6.0f); and so on. > void FastSinCos(long Angle, float *pSin, float *pCos) > { > float ang, sgn; > > ang = (Angle & 65535) * ((1.0f/65536.0f) * TwoPI); > > sgn = 1.0f; > if(ang >= (0.75f * TwoPI)) > ang -= TwoPI; > else if(ang >= (0.25f * TwoPI)) > { > ang -= 3.141592654f; > sgn = -1.0f; > } > > *pSin = (ang - (ang*ang*ang) * (1.0f/6.0f) + (ang*ang*ang*ang*ang) / > 120.0f) * sgn; > *pCos = (1.0f - (ang*ang / 2.0f) + (ang*ang*ang*ang) / 24.0f) *sgn; > } > > > Jason Dorie > BlackBoxGames > > > _______________________________________________ > GDAlgorithms-list mailing list > GDAlgorithms-list@... > http://lists.sourceforge.net/lists/listinfo/gdalgorithms-list _______________________________________________ GDAlgorithms-list mailing list GDAlgorithms-list@... http://lists.sourceforge.net/lists/listinfo/gdalgorithms-list ```

### Thread view

 [Algorithms] Fast simultaneous Sin() and Cos() From: Jason Dorie - 2001-03-14 19:41:38 ``` I know someone (Jason Zisk?) was looking for fast rotation matrix generation code. I realize that a Sin/Cos lookup table is the way to go for absolute speed, but if storage is a concern and the accuracy isn't, this code is about 5x faster than using the built-in sin and cos instructions, and accurate to about 4 decimal places. If you really want speed, and don't care about accuracy, drop the 2nd polynomial from each term. It's less accurate and faster still. It could probably be made even faster by replacing the if/else with branchless code, but I haven't bothered to figure out how yet. My angles are 0-65535 so that they can be masked into range easily, stored as shorts, and converted to normalized floats where necessary using SIMD instructions. void FastSinCos(long Angle, float *pSin, float *pCos) { float ang, sgn; ang = (Angle & 65535) * ((1.0f/65536.0f) * TwoPI); sgn = 1.0f; if(ang >= (0.75f * TwoPI)) ang -= TwoPI; else if(ang >= (0.25f * TwoPI)) { ang -= 3.141592654f; sgn = -1.0f; } *pSin = (ang - (ang*ang*ang) * (1.0f/6.0f) + (ang*ang*ang*ang*ang) / 120.0f) * sgn; *pCos = (1.0f - (ang*ang / 2.0f) + (ang*ang*ang*ang) / 24.0f) *sgn; } Jason Dorie BlackBoxGames ```
 Re: [Algorithms] Fast simultaneous Sin() and Cos() From: David Hunt - 2001-03-14 20:21:33 ```Surely all those ang*ang*angs are better done in steps. Ie float ang1=ang; *pSin=ang; ang*=ang1; // now squared *pCos=1.0f-ang/2; ang*=ang1; // now cubed *pSin-=ang*(1.0f/6.0f); and so on. > void FastSinCos(long Angle, float *pSin, float *pCos) > { > float ang, sgn; > > ang = (Angle & 65535) * ((1.0f/65536.0f) * TwoPI); > > sgn = 1.0f; > if(ang >= (0.75f * TwoPI)) > ang -= TwoPI; > else if(ang >= (0.25f * TwoPI)) > { > ang -= 3.141592654f; > sgn = -1.0f; > } > > *pSin = (ang - (ang*ang*ang) * (1.0f/6.0f) + (ang*ang*ang*ang*ang) / > 120.0f) * sgn; > *pCos = (1.0f - (ang*ang / 2.0f) + (ang*ang*ang*ang) / 24.0f) *sgn; > } > > > Jason Dorie > BlackBoxGames > > > _______________________________________________ > GDAlgorithms-list mailing list > GDAlgorithms-list@... > http://lists.sourceforge.net/lists/listinfo/gdalgorithms-list ```
 RE: [Algorithms] Fast simultaneous Sin() and Cos() From: Jason Dorie - 2001-03-14 21:30:32 ``` You're probably quite right, but I rearranged the code to do exactly that and got identical results. I'm guessing the compiler optimized it that way for me, so I changed the code back for readability. I am also aware that it is a taylor series, and that it only approximates the sin/cos functions in the range of +/- PI/2, which is why I have the range check / adjust code in the beginning. Jason -----Original Message----- From: gdalgorithms-list-admin@... [mailto:gdalgorithms-list-admin@...]On Behalf Of David Hunt Sent: Wednesday, March 14, 2001 12:25 PM To: gdalgorithms-list@... Subject: Re: [Algorithms] Fast simultaneous Sin() and Cos() Surely all those ang*ang*angs are better done in steps. Ie float ang1=ang; *pSin=ang; ang*=ang1; // now squared *pCos=1.0f-ang/2; ang*=ang1; // now cubed *pSin-=ang*(1.0f/6.0f); and so on. > void FastSinCos(long Angle, float *pSin, float *pCos) > { > float ang, sgn; > > ang = (Angle & 65535) * ((1.0f/65536.0f) * TwoPI); > > sgn = 1.0f; > if(ang >= (0.75f * TwoPI)) > ang -= TwoPI; > else if(ang >= (0.25f * TwoPI)) > { > ang -= 3.141592654f; > sgn = -1.0f; > } > > *pSin = (ang - (ang*ang*ang) * (1.0f/6.0f) + (ang*ang*ang*ang*ang) / > 120.0f) * sgn; > *pCos = (1.0f - (ang*ang / 2.0f) + (ang*ang*ang*ang) / 24.0f) *sgn; > } > > > Jason Dorie > BlackBoxGames > > > _______________________________________________ > GDAlgorithms-list mailing list > GDAlgorithms-list@... > http://lists.sourceforge.net/lists/listinfo/gdalgorithms-list _______________________________________________ GDAlgorithms-list mailing list GDAlgorithms-list@... http://lists.sourceforge.net/lists/listinfo/gdalgorithms-list ```
 Re: [Algorithms] Fast simultaneous Sin() and Cos() From: Dave Eberly - 2001-03-14 20:22:06 ```From: "Jason Dorie" The polynomials in your code are Taylor polynomials. Generally these are accurate only near the point of expansion (0, in these cases). Approximating polynomials of low degree with guaranteed global error bounds are at my magic-software site, numerical analysis page. -- Dave Eberly eberly@... http://www.magic-software.com http://www.wild-magic.com ```
 Re: [Algorithms] Fast simultaneous Sin() and Cos() From: Marco Corbetta - 2001-03-14 20:56:48 ```Hi, This is a modified version of your function using a (variable sized) sin lookup table,where you can pass any angle in radians as first parameter. Maybe someone can find it useful. void FastSinCos(float Angle, float *pSin, float *pCos) { int ang = (int)(SIN_TABLE_SIZE * Angle / (PI / 2)); int quadnum = ( ang >> SIN_TABLE_LOG2 ) & 3; ang &= (SIN_TABLE_SIZE-1); switch ( quadnum ) { case 0: *pSin=m_sintable[ang]; *pCos=m_sintable[(SIN_TABLE_SIZE-1)-ang]; break; case 1: *pSin=m_sintable[(SIN_TABLE_SIZE-1)-ang]; *pCos=-m_sintable[ang]; break; case 2: *pSin=-m_sintable[ang]; *pCos=-m_sintable[(SIN_TABLE_SIZE-1)-ang]; break; case 3: *pSin=-m_sintable[(SIN_TABLE_SIZE-1)-ang]; *pCos=m_sintable[ang]; break; } } Marco Corbetta Crytek Studios Inc. http://www.crytek.de ----- Original Message ----- From: "Jason Dorie" To: "GDAlgorithms" Sent: Wednesday, March 14, 2001 8:43 PM Subject: [Algorithms] Fast simultaneous Sin() and Cos() > > I know someone (Jason Zisk?) was looking for fast rotation matrix > generation code. I realize that a Sin/Cos lookup table is the way to go for > absolute speed, but if storage is a concern and the accuracy isn't, this > code is about 5x faster than using the built-in sin and cos instructions, > and accurate to about 4 decimal places. > > If you really want speed, and don't care about accuracy, drop the 2nd > polynomial from each term. It's less accurate and faster still. It could > probably be made even faster by replacing the if/else with branchless code, > but I haven't bothered to figure out how yet. > > > My angles are 0-65535 so that they can be masked into range easily, stored > as shorts, and converted to normalized floats where necessary using SIMD > instructions. > > > void FastSinCos(long Angle, float *pSin, float *pCos) > { > float ang, sgn; > > ang = (Angle & 65535) * ((1.0f/65536.0f) * TwoPI); > > sgn = 1.0f; > if(ang >= (0.75f * TwoPI)) > ang -= TwoPI; > else if(ang >= (0.25f * TwoPI)) > { > ang -= 3.141592654f; > sgn = -1.0f; > } > > *pSin = (ang - (ang*ang*ang) * (1.0f/6.0f) + (ang*ang*ang*ang*ang) / > 120.0f) * sgn; > *pCos = (1.0f - (ang*ang / 2.0f) + (ang*ang*ang*ang) / 24.0f) *sgn; > } > > > Jason Dorie > BlackBoxGames > > > _______________________________________________ > GDAlgorithms-list mailing list > GDAlgorithms-list@... > http://lists.sourceforge.net/lists/listinfo/gdalgorithms-list ```

## Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

No, thanks