A quickie Q about fast rounding floats to ints 
Author Message
 A quickie Q about fast rounding floats to ints

Hey, sometime ago someone said something about being able to round a
float to int with code something like this:

 float FIX = 24 * 65536 * 65536;
 int temp;

 _asm {
      fld dword ptr [float_number]    ;number to be rounded
      fadd dword ptr [FIX]
      fstp dword ptr [temp]              ;after adding the weird large
number, temp may now
  }                                                ;be simply used as an
int.
  return temp;

Atleast this does not work, but I am so sure the working version isn't
much different - just cannot remember/derive it myself. Any
recollections?

-matti

--
Author of GPF the 3D engine
http://www.*-*-*.com/



Tue, 25 Sep 2001 03:00:00 GMT  
 A quickie Q about fast rounding floats to ints

Quote:

> Hey, sometime ago someone said something about being able to round a
> float to int with code something like this:

>  float FIX = 24 * 65536 * 65536;
>  int temp;

>  _asm {
>       fld dword ptr [float_number]    ;number to be rounded
>       fadd dword ptr [FIX]
>       fstp dword ptr [temp]              ;after adding the weird large
> number, temp may now
>   }                                                ;be simply used as an
> int.
>   return temp;

> Atleast this does not work, but I am so sure the working version isn't
> much different - just cannot remember/derive it myself. Any
> recollections?

Adding the bias value (which must be larger than the maximum possible
input value) will make sure that the mantissa bits are aligned at a
fixed decimal position. By selecting the proper 'magic' bias, you can
get any kind of fixed-point representation, including zero fractional
bits.

You still have to strip away the top 9 bits (sign + exponent) of the
resulting dword though!

Terje

--

Using self-discipline, see http://www.eiffel.com/discipline
"almost all programming can be viewed as an exercise in caching"



Tue, 25 Sep 2001 03:00:00 GMT  
 A quickie Q about fast rounding floats to ints

Quote:

> Adding the bias value (which must be larger than the maximum possible
> input value) will make sure that the mantissa bits are aligned at a
> fixed decimal position. By selecting the proper 'magic' bias, you can
> get any kind of fixed-point representation, including zero fractional
> bits.

> You still have to strip away the top 9 bits (sign + exponent) of the
> resulting dword though!

I tried to implement this, but could not get it working. Do you have it
implemented yourself? I sure could use it. my current fast_ftol for C is
something like

_asm {
            fld    [float_number_to_be_rounded]
            fistp    [resulting_int]

Quote:
}

and I figure using the fadd trick with the bias value could be less expensive.
Any code out there?

thanks a lot in advance!

-matti-

--
Author of GPF the 3D engine
http://gpf-engine.dhs.org/



Wed, 26 Sep 2001 03:00:00 GMT  
 A quickie Q about fast rounding floats to ints

: Adding the bias value (which must be larger than the maximum possible
: input value) will make sure that the mantissa bits are aligned at a
: fixed decimal position. By selecting the proper 'magic' bias, you can
: get any kind of fixed-point representation, including zero fractional
: bits.

But that will still not work in precisely the same way as the compiler's
_ftol function does, will it? If you have access to them, Intel's CBT
PentiumII manuals have a suggestion for a replacement of the default _ftol
function that should provide the correct result in any case, whether your
number is positive, negative, NaN or inf or zero. It's around 20
instructions long though and I have not been able to verify that it works
properly. The idea behind the replacement is to avoid the floating point
unit state change which serializes the execution and thus can effectively
take dozens of processor cycles.

-pd

P.S. The CBT program I mentioned should be included with the VTune
performance analyzer CD.



Wed, 26 Sep 2001 03:00:00 GMT  
 A quickie Q about fast rounding floats to ints

Quote:

> But that will still not work in precisely the same way as the compiler's
> _ftol function does, will it? If you have access to them, Intel's CBT
> PentiumII manuals have a suggestion for a replacement of the default _ftol
> function that should provide the correct result in any case, whether your
> number is positive, negative, NaN or inf or zero. It's around 20
> instructions long though and I have not been able to verify that it works
> properly. The idea behind the replacement is to avoid the floating point
> unit state change which serializes the execution and thus can effectively
> take dozens of processor cycles.

argh, I'm not after precision or being able to handle NaN's rather than speed. 20
instructions will give minimun 20 clocks of cpu time, while with the addition thingy
I get about 5-10. I figure even using fld/fistp would be faster than that.

-matti-

--
Author of GPF the 3D engine
http://gpf-engine.dhs.org/



Wed, 26 Sep 2001 03:00:00 GMT  
 A quickie Q about fast rounding floats to ints

Believe it or not, i use the following code to convert floats & doubles to
ints... it may not be faster than a pure asm version, but as it is inline,
the compiler can optimize it for each context it is used, so it need not be
a separate call (i check the asm generated a while back and seem to recall
that apart from some missed pairing issues (which probably aren't so
importent anymore) it compiled to pretty much the same as a hand coded asm
version).

float g_dbl2intChop = 3 * pow(2,51);

inline int Int(double d)
{
     d -= 0.5;
     d += g_dbl2intChop;
     return *((int*)&d);

Quote:
}

the reason the -0.5 is there is because the default rounding mode is "round"
rather than what you want which is chop. In case you're wondering no you
cant just subtract the 0.5 from the magic number because the point five will
fall off the end of it... that's what makes it the magic number! Also this
method gives a 2's complement style signed, so...

Int(1.0) returns 1
Int(1.9) returns 1
Int(-1.0) returns -1
Int(-1.1) returns -2    // rather than (int)-1.1 = -1

This may seem dumb to some people but this form i actually find 10 times
more useful, especially if you're working with texture gradients and such.

if you want something that gives you standard int conversion (ie Int(-1.1)
= -1) then the best thing to do is change the rounding mode of the processor
to "round towards zero" and just{*filter*}it. That's what at least some
compilers do EVERY time you cast a float to an int, so you'd be speeding it
up a lot by changing "permanently" into that mode and using you're own{*filter*}
(on pentiums the mode change was very very expensive, and it probably isn't
cheap on the newer things)

WARNING! you may have to stick a "volatile" keyword or even some pragmas in
to make sure your compiler doesn't stuff up this code trying to optimize it
TOO much. If you were to change the order of the first 2 lines, you would
probably get (Round(d) - 1) as an answer.

BTW is this approach even necessary on pII and PIII? surely they've fixed
that bottleneck by now!?

Mark


Quote:
> Hey, sometime ago someone said something about being able to round a
> float to int with code something like this:

>  float FIX = 24 * 65536 * 65536;
>  int temp;

>  _asm {
>       fld dword ptr [float_number]    ;number to be rounded
>       fadd dword ptr [FIX]
>       fstp dword ptr [temp]              ;after adding the weird large
> number, temp may now
>   }                                                ;be simply used as an
> int.
>   return temp;

> Atleast this does not work, but I am so sure the working version isn't
> much different - just cannot remember/derive it myself. Any
> recollections?

> -matti

> --
> Author of GPF the 3D engine
> http://www.*-*-*.com/



Fri, 28 Sep 2001 03:00:00 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. Ints/Floats to Strings

2. converting floats, ints byte arrays

3. Converting floats to ints

4. Summary: Converting floats to ints quickly in C

5. using floats/ints in print and write

6. HDI: find the length of floats, ints?

7. : More on ints and floats

8. How to round a float?

9. How to round floating point to 2 decimal places

10. floating-point rounding problem

11. rounding floating point numbers

12. Challenge: Faster rounding towards 0

 

 
Powered by phpBB® Forum Software