c - Getting absolute value from a binary int using bit arithmetics -
flt32 flt32_abs (flt32 x) { int mask=x>>31; printmask(mask,32); puts("original"); printmask(x,32); x=x^mask; puts("after xor"); printmask(x,32); x=x-mask; puts("after x-mask"); printmask(x,32); return x; }
here's code, calling function on value -32 returning .125. i'm confused because it's pretty straight formula abs on bits, seem missing something. ideas?
is flt32
type floating point or fixed point numbers?
i suspect it's type fixed point arithmetic , not using correctly. let me explain it.
a fixed-point number uses, name says, fixed position decimal digit; means uses fixed number of bits decimal part. is, in fact, scaled integer.
i guess flt32
type using uses significant 24 bits whole part , least significant 8 bits decimal part; value real number of 32-bit representation value of same 32 bit representation integer, divided 256 (i.e. 28).
for example, 32-bit number 0x00000020
interpreted integer 32
. fixed-point number using 8
bits decimal part, value 0.125
(=32/256
).
the code posted correct not using correctly.
the number -32
encoded fixed-point number using 8
decimal digits 0xffffe000
integer representation of -8192
(=-32*256
). algorithm correctly produces 8192
0x00002000
(=32*256
); 32
when interpreted fixed-point.
if pass -32
function without taking care encode fixed-point, correctly converts 32
, returns value. 32
(0x00000020
) 0.125
(=1/8=32/256
) when interpreted fixed-point (what assume function printmask()
does).
how can test code correctly?
you have function creates fixed-point numbers integers. use correct representation of -32
, pass value flt32_abs()
function.
in case don't have such function, easy write it. multiply integer 256
(or better, left-shift 8 bits) , that's all:
function int_to_fx32(int x) { return x << 8; }
the fixed-point libraries use macros such conversions because produce faster code. expressed macro, looks this:
#define int_to_fx32(x) ((x) << 8)
now test:
fx32 negative = int_to_fx32(-32); fx32 positive = fx32_abs(negative); // should print 32 printmask(positive, 32); // should print 8192 printf("%d", positive); // should print -8192 printf("%d", negative); // should print 0.125 printmask(32, 32);
Comments
Post a Comment