|
Boost : |
From: Dan W. (danw_at_[hidden])
Date: 2003-12-12 11:08:41
> No need to go as far as using assembly language. There are C functions
> that work just fine like nearbyint or rint (the second one is usually
> faster). And if you are really looking for assembler, the frndint
> instruction is available on x86 for exemple.
Not familiar with those, but I just came up with something that should
work...
Instead of...
-------------------------------------------------------------------
template<class S>
struct Round
{
static source_type nearbyint ( argument_type s )
{
using std::floor ;
return floor( s + static_cast<S>(0.5) ) ;
}
typedef mpl::integral_c<std::float_round_style,std::round_to_nearest>
round_style ;
};
-------------------------------------------------------------------
I'd try the following (portability issues notwithstanding)
-------------------------------------------------------------------
struct Round
{
static source_type nearbyint ( argument_type s )
{
using std::floor ;
return depressed_avg( s, static_cast<S>(1.0) ) ;
}
typedef mpl::integral_c<std::float_round_style,std::round_to_nearest>
round_style ;
};
template <>
inline float depressed_avg<float>( float f, float onef )
{
float ret; //optimized away by inlining
__asm
{
mov eax,f ; optimized away by compiler
mov ebx,onef ; optimized away by compiler
dec ebx ; THE KEY INSTRUCTION dec mantissa by an LSB
add eax,eax ; double f first
add eax,ebx ; add the "slightly depressed one"
shrc eax ; shift right w/Carry, whatever the spelling was
mov ret,eax ; optimized away by compiler
}
return ret //optimized away by inlining
}
-------------------------------------------------------------------
(sorry if my syntax offends, I'm rusty in assembler these days)
That should add up to just four integer instructions, with optims' ON.
Not totally sure that the sign bit would always survive; would need to
test it.
Cheers!
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk