Connecting Tech Pros Worldwide Forums | Help | Site Map

Multiply float by -1: fast or slow?

Chris Stankevitz
Guest
 
Posts: n/a
#1: Jan 25 '07

Is this a fast way to invert a float:

inline Invert(float& f)
{
f *= -1.0f;
}

I'd like the CPU to flip the sign bit (and not carry out a float-float
multiplication). Please enlighten me! I'm going be performing a lot
of these.

Thanks,

Chris


Roman S.
Guest
 
Posts: n/a
#2: Jan 25 '07

re: Multiply float by -1: fast or slow?


Chris Stankevitz wrote:
Quote:
Is this a fast way to invert a float:
>
inline Invert(float& f)
{
f *= -1.0f;
}
>
I'd like the CPU to flip the sign bit (and not carry out a float-float
multiplication). Please enlighten me! I'm going be performing a lot
of these.
>
Thanks,
>
Chris
>
I think what you should do is:

inline Invert(float& f)
{
f = -f;
}
Ian Collins
Guest
 
Posts: n/a
#3: Jan 25 '07

re: Multiply float by -1: fast or slow?


Chris Stankevitz wrote:
Quote:
Is this a fast way to invert a float:
>
inline Invert(float& f)
Missing return type.
Quote:
{
f *= -1.0f;
}
>
I'd like the CPU to flip the sign bit (and not carry out a float-float
multiplication). Please enlighten me! I'm going be performing a lot
of these.
>
Try it, check the generated assembler. Your compiler should be able to
perform the required optimisation.

--
Ian Collins.
John Carson
Guest
 
Posts: n/a
#4: Jan 25 '07

re: Multiply float by -1: fast or slow?


"Chris Stankevitz" <chrisstankevitz@yahoo.comwrote in message
news:1169684324.050267.75260@k78g2000cwa.googlegro ups.com
Quote:
Is this a fast way to invert a float:
>
inline Invert(float& f)
{
f *= -1.0f;
}
>
I'd like the CPU to flip the sign bit (and not carry out a float-float
multiplication). Please enlighten me! I'm going be performing a lot
of these.

The only way to know is to test it. Different compilers will handle the same
code differently and different hardware platforms will have different
abilities.

On my computer

f = -f;

is slightly faster, but my computer can perform either operation about 100
million times per second. Code for testing:

#include <iostream>
#include <ctime>
using namespace std;

const int loops = 1000000000;

int main()
{
volatile float f = 345.898f;
int start = clock();
for(size_t i=0; i<loops; ++i)
f *= -1;
cout << ((double)clock()-time)/CLOCKS_PER_SEC << endl;

start = clock();
for(size_t i=0; i<loops; ++i)
f = -f;
cout << ((double)clock()-time)/CLOCKS_PER_SEC << endl;

return 0;
}

Note that tests like the above can't tell you exactly what speed you will
get in a real application, but they give you some idea.

--
John Carson


Victor Bazarov
Guest
 
Posts: n/a
#5: Jan 25 '07

re: Multiply float by -1: fast or slow?


Roman S. wrote:
Quote:
Chris Stankevitz wrote:
Quote:
>Is this a fast way to invert a float:
>>
>inline Invert(float& f)
>{
> f *= -1.0f;
>}
>>
>I'd like the CPU to flip the sign bit (and not carry out a
>float-float multiplication). Please enlighten me! I'm going be
>performing a lot of these.
>>
>Thanks,
>>
>Chris
>>
>
I think what you should do is:
>
inline Invert(float& f)
{
f = -f;
}
inline void Invert(float& f)
// ^^^^

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


Michael DOUBEZ
Guest
 
Posts: n/a
#6: Jan 25 '07

re: Multiply float by -1: fast or slow?


Chris Stankevitz a écrit :
Quote:
Is this a fast way to invert a float:
>
inline Invert(float& f)
{
f *= -1.0f;
}
>
I'd like the CPU to flip the sign bit (and not carry out a float-float
multiplication). Please enlighten me! I'm going be performing a lot
of these.
If you don't mind portability, you can simply flip it:
reinterpret_cast<char*>(&f)[sizeof(float)-1]^=0x80;

This is evil.

Michael
John Carson
Guest
 
Posts: n/a
#7: Jan 25 '07

re: Multiply float by -1: fast or slow?


"John Carson" <jcarson_n_o_sp_am_@netspace.net.auwrote in message
news:45b7f73b$0$11205$61c65585@uv-55king-reader-01.melbourne.pipenetworks.com.au
Quote:
>
Code for testing:
>
#include <iostream>
#include <ctime>
using namespace std;
>
const int loops = 1000000000;
>
int main()
{
volatile float f = 345.898f;
int start = clock();
for(size_t i=0; i<loops; ++i)
f *= -1;
cout << ((double)clock()-time)/CLOCKS_PER_SEC << endl;
// change time to start in previous line
Quote:
start = clock();
for(size_t i=0; i<loops; ++i)
f = -f;
cout << ((double)clock()-time)/CLOCKS_PER_SEC << endl;
// change time to start in previous line
Quote:
return 0;
}

--
John Carson


robertwessel2@yahoo.com
Guest
 
Posts: n/a
#8: Jan 25 '07

re: Multiply float by -1: fast or slow?




On Jan 24, 11:07 pm, Michael DOUBEZ <michael.dou...@free.frwrote:
Quote:
Chris Stankevitz a écrit :
>
Quote:
Is this a fast way to invert a float:
>
Quote:
inline Invert(float& f)
{
f *= -1.0f;
}
>
Quote:
I'd like the CPU to flip the sign bit (and not carry out a float-float
multiplication). Please enlighten me! I'm going be performing a lot
of these.If you don't mind portability, you can simply flip it:
reinterpret_cast<char*>(&f)[sizeof(float)-1]^=0x80;
>
This is evil.

Not only is it not portable, it doesn't work on (probably) the majority
of architectures out there. Mind you that the OP did not specify that
he was running on x86 or another machine which has IEEE-like floats
stored little endian. Even worse, your code may be substantially
slower than just a straight multiplication by -1 or negation since it
will almost certainly force the compiler to actually store the value in
memory before flipping the bit - something that would likely be avoided
if the value was already in a register, and the function actual got (as
requested) inlined. All quite implementation dependent, of course.

Ian Collins
Guest
 
Posts: n/a
#9: Jan 25 '07

re: Multiply float by -1: fast or slow?


Michael DOUBEZ wrote:
Quote:
Chris Stankevitz a écrit :
>
Quote:
>Is this a fast way to invert a float:
>>
>inline Invert(float& f)
>{
> f *= -1.0f;
>}
>>
>I'd like the CPU to flip the sign bit (and not carry out a float-float
>multiplication). Please enlighten me! I'm going be performing a lot
>of these.
>
>
If you don't mind portability, you can simply flip it:
reinterpret_cast<char*>(&f)[sizeof(float)-1]^=0x80;
>
Don't try and 2nd guess the compiler when it comes to this sort of
optimisation.
Quote:
This is evil.
>
It sure is.

--
Ian Collins.
Michael DOUBEZ
Guest
 
Posts: n/a
#10: Jan 25 '07

re: Multiply float by -1: fast or slow?


robertwessel2@yahoo.com a écrit :
Quote:
>
On Jan 24, 11:07 pm, Michael DOUBEZ <michael.dou...@free.frwrote:
Quote:
>Chris Stankevitz a écrit :
>>
Quote:
>>Is this a fast way to invert a float:
>>inline Invert(float& f)
>>{
>> f *= -1.0f;
>>}
>>I'd like the CPU to flip the sign bit (and not carry out a float-float
>>multiplication). Please enlighten me! I'm going be performing a lot
>>of these.If you don't mind portability, you can simply flip it:
>reinterpret_cast<char*>(&f)[sizeof(float)-1]^=0x80;
>>
>This is evil.
>
>
Not only is it not portable, it doesn't work on (probably) the majority
of architectures out there. Mind you that the OP did not specify that
he was running on x86 or another machine which has IEEE-like floats
stored little endian. Even worse, your code may be substantially
slower than just a straight multiplication by -1 or negation since it
will almost certainly force the compiler to actually store the value in
memory before flipping the bit - something that would likely be avoided
if the value was already in a register, and the function actual got (as
requested) inlined. All quite implementation dependent, of course.
>
Yes, it is evil. But, if you do something implementation dependant, well
you just do it.

And I expect this kind of trick to work on IEEE, IBM and VAX float since
they all put the sign bit on the MSB. Making a switch for litlle/big
endian is not really a big deal.

Concerning the perfs, I didn't make any bench but the truth is that bit
operations on float are forbidden so unless the compiler optimize the
operation (-() or *-1.0f) alternatives are equivalent.

Now, this is not something I would do but worth a try.

Michael
Michael DOUBEZ
Guest
 
Posts: n/a
#11: Jan 25 '07

re: Multiply float by -1: fast or slow?


Michael DOUBEZ a écrit :
Quote:
robertwessel2@yahoo.com a écrit :
Quote:
>>
>On Jan 24, 11:07 pm, Michael DOUBEZ <michael.dou...@free.frwrote:
Quote:
>>Chris Stankevitz a écrit :
>>>
>>>Is this a fast way to invert a float:
>>>inline Invert(float& f)
>>>{
>>> f *= -1.0f;
>>>}
>>>I'd like the CPU to flip the sign bit (and not carry out a float-float
>>>multiplication). Please enlighten me! I'm going be performing a lot
>>>of these.If you don't mind portability, you can simply flip it:
>>reinterpret_cast<char*>(&f)[sizeof(float)-1]^=0x80;
>>>
>>This is evil.
>>
>>
>Not only is it not portable, it doesn't work on (probably) the majority
>of architectures out there. Mind you that the OP did not specify that
>he was running on x86 or another machine which has IEEE-like floats
>stored little endian. Even worse, your code may be substantially
>slower than just a straight multiplication by -1 or negation since it
>will almost certainly force the compiler to actually store the value in
>memory before flipping the bit - something that would likely be avoided
>if the value was already in a register, and the function actual got (as
>requested) inlined. All quite implementation dependent, of course.
>
Concerning the perfs, I didn't make any bench but the truth is that bit
operations on float are forbidden so unless the compiler optimize the
operation (-() or *-1.0f) alternatives are equivalent.
>
Now, this is not something I would do but worth a try.
Making a quick try, it is slower to cast.

Michael


Closed Thread