   How to do fast floating-point multiplication by 1, 0, and -1?
  I have two single-percision floating-point variables, which I need to multiply as quickly as possible (this is done many times in a loop). One of the variables can potentially contain any real number, but the other is known to contain either 1, 0, or -1. I don't know in advance which of the three is contained in that variable.Given this situation, how can I optimize the multiplication? Is it perhaps possible to encode 1, 0, and -1 as some other special values and do the multiplication with bitwise operations (that would be the optimal solution, I think)? Is there some other way?EDIT: Is this supposed to go into the General Programming forum instead?....Michael K.,  Co-designer and Graphics Programmer of "The Keepers"We come in peace... surrender or die! [edited by - technobot on July 27, 2003 3:19:49 PM]
  if you just had -1 and 1 you could encode -1 as 0x80000000 and 1 as 0, and than you could do an integer xor.c = a ^ b;This will work, but I don''t think it will be faster, since fmul costs 1 clock tick on modern cpu''s, and if you want to do other floating point opts on them after this, they can be kept in the floating point registers if you use fmul. I think just using fmul, or an sse equivalent will be the best way.   My Site;  quasar, I''m not as skilled as you, but I know the IEEE format.  How would xoring two sign bits which equal 0, give c a negative sign?  Say you''re multiplying by -1 (0x80000000), alright?...so xoring that int with a positive or zero float would be bluntly: 0x800000000XOR0xMantissa^Exponent0 XOR 0 is 0, when that sign bit should be 1, I think.  Because + * - = negative.  Something''s screwy.   ;  0x is the prefix for hexadecimal. It doesn''t indicate a leading ''0'' bit. [ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ][ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ] ;  Um... if (x == 0.0f)    result = 0.0f;else if (x == -1.0f)    result = -y;else    result = y;Would that be fast enough?   The following statement is true. The previous statement is false.Shameless promotion:FreePop: The GPL Populous II clone.;  You should probably just use fmul, any tricks you pull otherwise will just eat up an integer register and probably take more cycles. You might be able to get a speedup by ordering the arguments well, but that might already be done internally. ;  that and... NEVER TEST FLOATS FOR EQUALITY. :D ;  Using conditions is not an option, as the multiplications are part of a more complex calculation, and there are several such multiplications per calculation. I.e. something like:result1 = (bla1 * bla2) + (bla3 * bla4) + (bla5 * bla6);result2 = (bla7 * bla8) + (bla9 * bla10) + (bla11 * bla12);result3 = interpolate(result1, result2, factor);Basically, this is part of the improved version of Ken Perlin's perlin noise, as described in this paper. One of the improvement is to use specially selected gradient vectors whose components can only be 1, 0, or -1.Part of the algorithm is a series of dot products between those vectors and certain other vectors. In the performance section of the paper, Ken Perlin writes: "... the new algorithm runs approximately 10 percent faster than the original. The cost of the extra multiplies required to compute the three corrected interpolants is apparently outweighted by the savings from the multiplies no longer required to compute the eigth inner products  .  ".What bugs me is: how are the dot (inner) products eliminated??   EDIT: Only 1 cycle for an fmul? Hmm... that's interesting...Michael K.,  Co-designer and Graphics Programmer of "The Keepers"We come in peace... surrender or die!  [edited by - technobot on July 28, 2003 4:09:15 PM];  A couple questions:1. Will the variables that are -1, 0, or 1 be set to the constants -1/0/1, or will mathematical calculations produce these numbers?2. In the equations you just showed us, which are the variables that are 0/1/-1?   How appropriate. You fight like a cow. ;  what he (perlin) talks about is actually hw implementation. THERE mults are expensive, THERE replacing it by some simple bitwise logic to "multiply" -1,0,1 together is useful. it replaces a full fpu multiplier for 32bit floats (or similar) by some and|or logic for 2bits.. or even a lookuptable for the actual product is enough..dotproduct[(a<<4)|(b<<2)|c] where a,b,c = {0,1,2} with mapping 0 := -1.f, 1 := 0.f, 2 = 1.fevery hw implementation of what ever just LOVES to not use any floatingpoint math where needed.just expensive processors are directly made to be fast on fpu''s.. and slow on switching between fpu and integer unit (passing values there around..).the only place where i''d see the possible optimisation to gain performance _could_ be in SSE, where you can just and,or,xor a bitmask, and anding/xoring a bitmask is enough to multiply a float by -1,0,1 i think..   "take a look around" - limp bizkitwww.google.com 