I wonder if there is a fast way to get the fractional value a value between 0.0 and 1.0

If for example the value is:

22.5

I would like to get the 0.5 value.

I wonder if there is a fast way to do so?

If for example the value is:

22.5

I would like to get the 0.5 value.

I wonder if there is a fast way to do so?

What do you mean? Clamping usually would give 1.0 for 22.5?

I don't understand - what is the transformation you'd like to occur over the range of possible input values? MMX is the fastest clamping I know of - using the saturation instructions.

This question is more of an algorithm question. IMHO ;)

I don't understand - what is the transformation you'd like to occur over the range of possible input values? MMX is the fastest clamping I know of - using the saturation instructions.

This question is more of an algorithm question. IMHO ;)

I think he just wants to get the fractional part?

duh, I feel so stupid. ;)

fld st

frndint

fsubp

But this produces all kinds of results dependant on the rounding mode!

Or:

fist DWORD PTR

fisub DWORD PTR

Same problem. Set rounding mode to truncate for desired results.

**dxantos**, I assume your using FPU?fld st

frndint

fsubp

But this produces all kinds of results dependant on the rounding mode!

Or:

fist DWORD PTR

fisub DWORD PTR

Same problem. Set rounding mode to truncate for desired results.

I edited the original post. I was using the incorrect term, clamping instead of fractional part.

I mean not using the FPU the real4 is defined this way:

And for example if you want to see is a value is negative, positive or zero, without using the FPU, you could do this:

Since the bit31 is the sign bit on both float and integers, and 0 is the same in both float and integer. this trick works (but only for comparing with 0).

and you change it to and absolute value without passing to the FPU using this algo:

You can even clamp a value to 0 if its negative with this one:

So I wonder if there is a trick to get the fractional value of a float (real4).

I mean not using the FPU the real4 is defined this way:

```
```

s eeeeeeee mmmmmmmmmmmmmmm

s = sign bit

e = exponent bits

m = mantisa bits

And for example if you want to see is a value is negative, positive or zero, without using the FPU, you could do this:

```
```

mov eax, [floatValue]

cmp eax, 0

Since the bit31 is the sign bit on both float and integers, and 0 is the same in both float and integer. this trick works (but only for comparing with 0).

and you change it to and absolute value without passing to the FPU using this algo:

```
```

mov eax, [floatValue]

and eax, 7FFFFFFFh ;The sign is the last bit, 0 = positive or zero.

mov [floatValue], eax

You can even clamp a value to 0 if its negative with this one:

```
```

mov edx, [floatVal]

mov eax, edx

sar eax, 31 ; This will put the sign bit on every bit

not eax ; Flips the bits. will be 0 if negative, 0FFFFFFFFh otw

and edx, eax ; Change value to zero if negative

mov [floatVal], eax

So I wonder if there is a trick to get the fractional value of a float (real4).

There's a problem with the "integer compare to 0" method, though.

If you work a lot with the floating-point numbers, you risk building

up small errors, so you can have a value that *should* be 0, but

is rather 0.000000000001 (or whatever). Also, I believe floating

point values can be both +0 and -0 (which is pretty weird in when

thinking strictly mathematical... but floats

Now, those statements are only based on stuff I've heard and such,

I haven't messed extremely much with floats, especially not where

precision was needed (I let my friend do that... I coded the fun stuff,

my friend had the chore of translating ugly mathematical expressions

into C code. Grin.)

If you work a lot with the floating-point numbers, you risk building

up small errors, so you can have a value that *should* be 0, but

is rather 0.000000000001 (or whatever). Also, I believe floating

point values can be both +0 and -0 (which is pretty weird in when

thinking strictly mathematical... but floats

**are**only approximations.)Now, those statements are only based on stuff I've heard and such,

I haven't messed extremely much with floats, especially not where

precision was needed (I let my friend do that... I coded the fun stuff,

my friend had the chore of translating ugly mathematical expressions

into C code. Grin.)

**f0dder:**You are right, the value:

1 00000000 000000000000000000000000 b

is zero, altough it will pass as a negative.

Also if the exponent is 0 the number is a very tiny number, so near 0 that should be considered zero.

Thus:

```
```

mov eax, [floatVal]

test eax, 07F800000 ; Test if exponent is zero.

jz @f

cmp eax, 0

@@:

would be a more appropiate comparison, that dont care about negative zero. But this also mean a possible jump.

also if you want it to be precise to lets say 0.001

(well actually 1/(2^10) )

```
```

mov edx, [floatVal]

mov eax, edx

and edx, 07F800000

.if edx < (127 - 10) * 800000h ; 1/(2^10)

;{

sub edx, edx ; Set flag to zero

;}

.else

;{

cmp eax, 0

;}

.endif

for a 0.000001 precision (actually 1/(2^20) change the 10 to 20

I didn't take into account when the exponent is 255, this means the value is either a NAN, positive infinity or negative infinity. Fortunately this is rare, (unless you work with too big numbers). (To be honest I do not now what a number that is not a number "NAN" means). :)

**bitRAKE :**Thanks for your answer. Most of the time I leave the FPU on rounding mode, not truncate thus this will be slow for me to switch the FPU state for a single value.

Sorry to include this question in the game programming one.

I tough the algorithm section was to submit algorithms, and not asking for one. (I feel dumb).

For my uses the truncate mode offers more chances of optimization, and I can change most other alorithms to use that mode.