Velocity Reviews > bitwise on float

# bitwise on float

Carramba
Guest
Posts: n/a

 05-18-2007
Walter Roberson skrev:
> In article <464db100\$0\$13493\$(E-Mail Removed)>,
> Carramba <(E-Mail Removed)> wrote:
>> I now that I can't do straight forward any bitwise operation on float
>> (double etc..). But I wondering what is the easiest/best way to do this?

>
> Not to.
>
>> I was thinking if I have float x=1.1111 so I can multiple it by 1000 to
>> get 11111 and the preform bitwise like <<2 to get 88888 and then divide
>> by 1000 to go back to float 8.8888. but these seem like "nasty" way to
>> do it. So maybe some of you have great tips?

>
> floats might not happen to be the same size as an integral type,
> so if you are absolutely determined to do bitwise operations on them,
> you will have to use something like,
>
> float_as_bits_p = (unsigned char *)&the_float;
>
> to gain access to the bits. This will give you an object of
> length sizeof the_float but the bit ordering within that array
> will be completely undefined. Do not use plain or signed char
> for this purpose: plain or unsigned char can have 'trap bits'
> that unsigned char is guaranteed not to have.
>
> The other posters referred you to
> functions that break apart doubles into exponent and mantissa;
> what they didn't note (because it is outside the scope of C proper)
> is that in IEEE 754 there is a "hidden bit" in the binary
> representation: because the normalized mantissa will always start
> with binary 1, the binary 1 will not actually be stored. This will
>
> There are no C operators to do << or + or | or whatever across
> entire arrays of unsigned char, so you will have to do each char
> one at a time and "manually" propogate carry bits and borrows and
> rolling in to the next bucket and so on.
>
> Don't forget to manually re-normalize the numbers before
> constructing the final float. Oh, and watch out because neither
> the exponent nor the mantissa are two's complement.
>
> If any of this isn't making immediate sense to you, chances are
> good that you shouldn't attempt to do this.

No all of it makes sense... and I was afraid that I will need to "break"
float apart..and perform bitwise on exponent and mantissa.. and as u say
it can easy get messy...

thank you

Carramba
Guest
Posts: n/a

 05-18-2007
Clark Cox skrev:
> On 2007-05-18 12:18:19 -0700, Carramba <(E-Mail Removed)> said:
>
>> user923005 skrev:
>>> On May 18, 7:15 am, Carramba <(E-Mail Removed)> wrote:
>>>> Hi!
>>>> I now that I can't do straight forward any bitwise operation on float
>>>> (double etc..). But I wondering what is the easiest/best way to do
>>>> this?
>>>> I was thinking if I have float x=1.1111 so I can multiple it by 1000 to
>>>> get 11111 and the preform bitwise like <<2 to get 88888 and then divide
>>>> by 1000 to go back to float 8.8888. but these seem like "nasty" way to
>>>> do it. So maybe some of you have great tips?
>>>
>>> If you just want to do math with it, then all of that is a complete
>>> waste of time.

>>
>> neither or... as I stated earlier I need to perform bitwise operation
>> on float.

>
> No, you don't. That is, "perform bitwise operations on float" cannot be
> your ultimate goal. You *think* that it is a step required to reach your
> goal (whatever it is), but I can assure you that it is not. What do you
> *really* want to do?

well yes it is...
way is it easier to thing that because one ask for help that person is
stupid? and doesn't know a think?

>> right now I program works only on integer values, and thus precision
>> is "ok". but in order to get really nice precision I need floats, and
>> bitwise operations on them

>
> You said that you wanted to start with 1.1111 and get 8.8888. What's
> wrong with:

bad exemple.. 1.1111 and 8.8888 have nothing to do with real numbers..
was just trying to make pa point. obviously I have failed.
> new = old * (1<<2);
>
> ?
>

Clark Cox
Guest
Posts: n/a

 05-18-2007
On 2007-05-18 13:09:56 -0700, Carramba <(E-Mail Removed)> said:

> Clark Cox skrev:
>> On 2007-05-18 12:18:19 -0700, Carramba <(E-Mail Removed)> said:
>>
>>> user923005 skrev:
>>>> On May 18, 7:15 am, Carramba <(E-Mail Removed)> wrote:
>>>>> Hi!
>>>>> I now that I can't do straight forward any bitwise operation on float
>>>>> (double etc..). But I wondering what is the easiest/best way to do this?
>>>>> I was thinking if I have float x=1.1111 so I can multiple it by 1000 to
>>>>> get 11111 and the preform bitwise like <<2 to get 88888 and then divide
>>>>> by 1000 to go back to float 8.8888. but these seem like "nasty" way to
>>>>> do it. So maybe some of you have great tips?
>>>>
>>>> If you just want to do math with it, then all of that is a complete
>>>> waste of time.
>>>
>>> neither or... as I stated earlier I need to perform bitwise operation
>>> on float.

>>
>> No, you don't. That is, "perform bitwise operations on float" cannot be
>> your ultimate goal. You *think* that it is a step required to reach
>> your goal (whatever it is), but I can assure you that it is not. What
>> do you *really* want to do?

>
> well yes it is...
> way is it easier to thing that because one ask for help that person is
> stupid? and doesn't know a think?

I'm not sure how to parse those sentences. Try to rephrase your
question. What exactly do you want to do to the value of the float?
From your example above, it seems that you want to multiply it by a
power of 2.

>>> right now I program works only on integer values, and thus precision is
>>> "ok". but in order to get really nice precision I need floats, and
>>> bitwise operations on them

>>
>> You said that you wanted to start with 1.1111 and get 8.8888. What's
>> wrong with:

>
> bad exemple.. 1.1111 and 8.8888 have nothing to do with real numbers..
> was just trying to make pa point. obviously I have failed.

Then try a better example.

>> new = old * (1<<2);
>>
>> ?

--
Clark S. Cox III
http://www.velocityreviews.com/forums/(E-Mail Removed)

user923005
Guest
Posts: n/a

 05-18-2007
On May 18, 1:06 pm, Carramba <(E-Mail Removed)> wrote:
> Walter Roberson skrev:
>
>
>
> > In article <464db100\$0\$13493\$(E-Mail Removed)>,
> > Carramba <(E-Mail Removed)> wrote:
> >> I now that I can't do straight forward any bitwise operation on float
> >> (double etc..). But I wondering what is the easiest/best way to do this?

>
> > Not to.

>
> >> I was thinking if I have float x=1.1111 so I can multiple it by 1000 to
> >> get 11111 and the preform bitwise like <<2 to get 88888 and then divide
> >> by 1000 to go back to float 8.8888. but these seem like "nasty" way to
> >> do it. So maybe some of you have great tips?

>
> > floats might not happen to be the same size as an integral type,
> > so if you are absolutely determined to do bitwise operations on them,
> > you will have to use something like,

>
> > float_as_bits_p = (unsigned char *)&the_float;

>
> > to gain access to the bits. This will give you an object of
> > length sizeof the_float but the bit ordering within that array
> > will be completely undefined. Do not use plain or signed char
> > for this purpose: plain or unsigned char can have 'trap bits'
> > that unsigned char is guaranteed not to have.

>
> > The other posters referred you to
> > functions that break apart doubles into exponent and mantissa;
> > what they didn't note (because it is outside the scope of C proper)
> > is that in IEEE 754 there is a "hidden bit" in the binary
> > representation: because the normalized mantissa will always start
> > with binary 1, the binary 1 will not actually be stored. This will
> > complicate your bit manipulations.

>
> > There are no C operators to do << or + or | or whatever across
> > entire arrays of unsigned char, so you will have to do each char
> > one at a time and "manually" propogate carry bits and borrows and
> > rolling in to the next bucket and so on.

>
> > Don't forget to manually re-normalize the numbers before
> > constructing the final float. Oh, and watch out because neither
> > the exponent nor the mantissa are two's complement.

>
> > If any of this isn't making immediate sense to you, chances are
> > good that you shouldn't attempt to do this.

>
> No all of it makes sense... and I was afraid that I will need to "break"
> float apart..and perform bitwise on exponent and mantissa.. and as u say
> it can easy get messy...

The functions I showed you ldexp()/frexp() are used for that purpose.
I guess that you are going to try to make the math faster by this.
It's not going to work.
You might think of a simple case:
I want to multiply by 2, so I pull out the exponent, add 1 to it, and
put it back (after all, the exponent is in base 2)! Voilla!
Multiplication by 2 and I did not even have to multiply!
Now, figure out the cost of the two function calls and compare it to
the cost of one floating point multiply and you will discover it is a
big loser.

What is it that you are really trying to do with these floating point
numbers? You will find that modern FPUs are amazingly fast and so it
is going to be very difficult to do any manipulations that are going
to outperform the same concepts as by standard floating point
operations.

John Cochran
Guest
Posts: n/a

 05-18-2007
In article <464e0262\$0\$13207\$(E-Mail Removed)>,
Carramba <(E-Mail Removed)> wrote:
>John Cochran skrev:
>> In article <464df809\$0\$13214\$(E-Mail Removed)>,
>> Carramba <(E-Mail Removed)> wrote:
>>> user923005 skrev:
>>>> On May 18, 7:15 am, Carramba <(E-Mail Removed)> wrote:
>>>>> Hi!

SNIP
>>
>> One thing you haven't mentioned and you should is WHY you are performing
>> bitwise operations. If you tell us what you are attempting to acomplish,
>> then we might be able to help you better. And DON'T say that what you need
>> to do is perform bitwise manipulation of floating point numbers. Do not
>> simply ask for help on what you believe to be a step in solving your problem,

>
>Some time it's strange that one can't by taken by word and believed ...
>I'm working with genetic algorithms, and have implemented it in C. in
>order to work one need to perform crossover and bitflip operations on
>encoded data.
>crossover - take two values represented by binary string and, "cast a
>coin" and exchange part of those strings -> bitmask operation
>bitflip - cast a coin and flip bit in that place.
>
>reason one:
>since this is not forum for genetic algorithms I didn't bother to
>explain earlier, and it would take more than this little peace to
>explain in details what I'm doing
>reason two:
>because in the I have been shouted and treat malicious then I have
>posted something that wasn't related to ansi c. and underlying problem
>isn't so I just posted only what are my intentions to do.

OK, I'm snipping everything that looks like you're getting upset and/or
insulting or thinking you're being insulted.

If I understand you correctly, you need to do bit operations on something
larger than what you can get using integers and you think that by using
floating point numbers, you'll somehow succeed.

Problem: Bit operations on floating point numbers ARE NOT DEFINED AND WILL NOT WORK.
Period. End of discussion. Case closed.

Additionally, doing said operations on floating point numbers will not get you
more bits than what you can get by using integral types. To demonstrate, execute
the following short program.

#include <stdio.h>

int main(void)
{
printf("short = %d\n", (int)sizeof(short));
printf("int = %d\n", (int)sizeof(int));
printf("long = %d\n", (int)sizeof(long));
printf("long long = %d\n", (int)sizeof(long long));
printf("float = %d\n", (int)sizeof(float));
printf("double = %d\n", (int)sizeof(double));
printf("long double = %d\n", (int)sizeof(long double));
return 0;
}

Note: Some implementations of C will not support long long or long double. If so,
just ommit those lines that mention it.

The numbers generated by this simple program is simply the number of bytes each
type takes up. Multiply by 8 to get the number of bits available for manipulation.
I would not be surprised if the output of the above program is something like

2
4
4
8
4
8
10

As you can see, none of the above numbers is really large and is likely to be
unsuitable for genetic algorithms assuming you need more than about 64 bits.

So since none of the primitive data types available is suitable for you, you'll
have to use a composite data type and make functions to manipulate them. I'd
suggest that you use as your basic component an array in integral values with the
actual integral type dependent on the native word size of your computer. The type
"unsigned int" comes to mind as a reasonable start. Then write some functions
designed to create/destroy/manipulate these arrays.

For example:
(Error checking omitted for clarity. Code untested....)

#include <stdlib.h>

typedef struct {
size_t len;
unsigned int *array;
} BIT_ARRAY;

BIT_ARRAY *create_ba(size_t size)
{
BIT_ARRAY *p;

p = malloc(sizeof(*p));
p->len = size;
p->array = calloc(sizeof(unsigned int), p->len);
return p;
}

void create_ba(BIT_ARRAY *p)
{
free(p->array);
free(p);
}

BIT_ARRAY *and_ba(BIT_ARRAY *a, BIT_ARRAY *b)
{
size_t len,x;
BIT_ARRAY *p;

len = (a->len < b->len) ? a->len : b->len;

p = create_ba(len);

for(x=0; x<len; ++x) {
p->array[x] = a->array[x] & b->array[x];
}
return p;
}

etc. etc. etc.

Sorry, but this is the best that you can do. And if someone on this group says
that what you're doing doesn't make sense, it doesn't mean that they think you're
and idiot. It at worst means that you're ignorant about the language. Just remember:

Ignorance is curable, stupidity isn't.

It's OK to be ignorant if you're willing to be educated. If you're not willing to
be educated, then I have to assume that you're not ignorant, but instead you're
stupid. Don't be stupid.

user923005
Guest
Posts: n/a

 05-18-2007
On May 18, 2:40 pm, (E-Mail Removed) (John Cochran) wrote:
> In article <464e0262\$0\$13207\$(E-Mail Removed)>,
>
>
>
>
>
> Carramba <(E-Mail Removed)> wrote:
> >John Cochran skrev:
> >> In article <464df809\$0\$13214\$(E-Mail Removed)>,
> >> Carramba <(E-Mail Removed)> wrote:
> >>> user923005 skrev:
> >>>> On May 18, 7:15 am, Carramba <(E-Mail Removed)> wrote:
> >>>>> Hi!

> SNIP
>
> >> One thing you haven't mentioned and you should is WHY you are performing
> >> bitwise operations. If you tell us what you are attempting to acomplish,
> >> then we might be able to help you better. And DON'T say that what you need
> >> to do is perform bitwise manipulation of floating point numbers. Do not
> >> simply ask for help on what you believe to be a step in solving your problem,

>
> >Some time it's strange that one can't by taken by word and believed ...
> >I'm working with genetic algorithms, and have implemented it in C. in
> >order to work one need to perform crossover and bitflip operations on
> >encoded data.
> >crossover - take two values represented by binary string and, "cast a
> >coin" and exchange part of those strings -> bitmask operation
> >bitflip - cast a coin and flip bit in that place.

>
> >reason one:
> >since this is not forum for genetic algorithms I didn't bother to
> >explain earlier, and it would take more than this little peace to
> >explain in details what I'm doing
> >reason two:
> >because in the I have been shouted and treat malicious then I have
> >posted something that wasn't related to ansi c. and underlying problem
> >isn't so I just posted only what are my intentions to do.

>
> OK, I'm snipping everything that looks like you're getting upset and/or
> insulting or thinking you're being insulted.
>
> If I understand you correctly, you need to do bit operations on something
> larger than what you can get using integers and you think that by using
> floating point numbers, you'll somehow succeed.
>
> Problem: Bit operations on floating point numbers ARE NOT DEFINED AND WILL NOT WORK.
> Period. End of discussion. Case closed.
>
> Additionally, doing said operations on floating point numbers will not get you
> more bits than what you can get by using integral types. To demonstrate, execute
> the following short program.
>
> #include <stdio.h>
>
> int main(void)
> {
> printf("short = %d\n", (int)sizeof(short));
> printf("int = %d\n", (int)sizeof(int));
> printf("long = %d\n", (int)sizeof(long));
> printf("long long = %d\n", (int)sizeof(long long));
> printf("float = %d\n", (int)sizeof(float));
> printf("double = %d\n", (int)sizeof(double));
> printf("long double = %d\n", (int)sizeof(long double));
> return 0;
>
> }
>
> Note: Some implementations of C will not support long long or long double. If so,
> just ommit those lines that mention it.

Those that do not support long double are broken because it is a
requirement of the language.
On the other hand, long double does not have to be larger than double.

> The numbers generated by this simple program is simply the number of bytes each
> type takes up. Multiply by 8 to get the number of bits available for manipulation.
> I would not be surprised if the output of the above program is something like
>
> 2
> 4
> 4
> 8
> 4
> 8
> 10
>
> As you can see, none of the above numbers is really large and is likely to be
> unsuitable for genetic algorithms assuming you need more than about 64 bits.
>
> So since none of the primitive data types available is suitable for you, you'll
> have to use a composite data type and make functions to manipulate them. I'd
> suggest that you use as your basic component an array in integral values with the
> actual integral type dependent on the native word size of your computer. The type
> "unsigned int" comes to mind as a reasonable start. Then write some functions
> designed to create/destroy/manipulate these arrays.
>
> For example:
> (Error checking omitted for clarity. Code untested....)
>
> #include <stdlib.h>
>
> typedef struct {
> size_t len;
> unsigned int *array;
>
> } BIT_ARRAY;
>
> BIT_ARRAY *create_ba(size_t size)
> {
> BIT_ARRAY *p;
>
> p = malloc(sizeof(*p));
> p->len = size;
> p->array = calloc(sizeof(unsigned int), p->len);
> return p;
>
> }
>
> void create_ba(BIT_ARRAY *p)
> {
> free(p->array);
> free(p);
>
> }
>
> BIT_ARRAY *and_ba(BIT_ARRAY *a, BIT_ARRAY *b)
> {
> size_t len,x;
> BIT_ARRAY *p;
>
> len = (a->len < b->len) ? a->len : b->len;
>
> p = create_ba(len);
>
> for(x=0; x<len; ++x) {
> p->array[x] = a->array[x] & b->array[x];
> }
> return p;
>
> }
>
> etc. etc. etc.
>
> Sorry, but this is the best that you can do. And if someone on this group says
> that what you're doing doesn't make sense, it doesn't mean that they think you're
> and idiot. It at worst means that you're ignorant about the language. Just remember:
>
> Ignorance is curable, stupidity isn't.
>
> It's OK to be ignorant if you're willing to be educated. If you're not willing to
> be educated, then I have to assume that you're not ignorant, but instead you're
> stupid. Don't be stupid.- Hide quoted text -

Maybe he wants a multiple precision number library like GMP.
Personally, I am fond of MPFR.
http://pari.math.u-bordeaux.fr/benchs/timings-mpfr.html

James Dow Allen
Guest
Posts: n/a

 05-19-2007
On May 19, 3:02 am, Carramba <(E-Mail Removed)> wrote:
> Some time it's strange that one can't by taken by word and believed ...
> I'm working with genetic algorithms, and have implemented it in C. in
> order to work one need to perform crossover and bitflip operations on
> encoded data [in floating point format].

It should be straightforward to achieve what you want
with unions.

A more interesting question is whether GA operations
really make sense on floating-point numbers, or, more
generally with any numbers with many sig digits.
I'm certainly no GA expert, but GA ops rely that it
makes sense, given a good candidate
AAAAAAAAABBBBBBB
to try a possibly better candidate
AAAAAACCCCCCCBBB
but how can preserving BBB make sense if they are the
LSB's of the number you just altered?

GA'ers I've talked to used "thermometer code" even
for numbers with few sig digits, and didn't do GA ops
on many-sig digit numbers at all.

James Dow Allen

Walter Roberson
Guest
Posts: n/a

 05-19-2007
In article <(E-Mail Removed) .com>,
James Dow Allen <(E-Mail Removed)> wrote:
>On May 19, 3:02 am, Carramba <(E-Mail Removed)> wrote:
>> Some time it's strange that one can't by taken by word and believed ...
>> I'm working with genetic algorithms, and have implemented it in C. in
>> order to work one need to perform crossover and bitflip operations on
>> encoded data [in floating point format].

>It should be straightforward to achieve what you want
>with unions.

No.

First off, float/double are not certain to be the same length
as any integral type, so you'd end up having to do a union with
an array of unsigned char, with all the problems associated with
the approach of casting the address of the float to pointer to
unsigned char that I dicussed earlier.

Secondly, it is undefined behaviour to access a union
member through a type other than the last type that was used
to store the variable (unless the new access type is a structure
of identical type elements -- the "prefix" rule.)
--
Okay, buzzwords only. Two syllables, tops. -- Laurie Anderson

christian.bau
Guest
Posts: n/a

 05-19-2007
On May 18, 3:15 pm, Carramba <(E-Mail Removed)> wrote:
> Hi!
> I now that I can't do straight forward any bitwise operation on float
> (double etc..). But I wondering what is the easiest/best way to do this?
> I was thinking if I have float x=1.1111 so I can multiple it by 1000 to
> get 11111 and the preform bitwise like <<2 to get 88888 and then divide
> by 1000 to go back to float 8.8888. but these seem like "nasty" way to
> do it. So maybe some of you have great tips?

Your post has lead to quite a long and rather pointless debate. You
could help by telling us: What is it actually that you are trying to
how you could achieve this. Tell us _what_ you want to achieve.

For example, given two floating numbers x = 3.1415 and y = 2.7128,
what would be the result that you expect?

Walter Roberson
Guest
Posts: n/a

 05-19-2007
In article <(E-Mail Removed) .com>,
christian.bau <(E-Mail Removed)> wrote:
>On May 18, 3:15 pm, Carramba <(E-Mail Removed)> wrote:
>> Hi!
>> I now that I can't do straight forward any bitwise operation on float
>> (double etc..). But I wondering what is the easiest/best way to do this?
>> I was thinking if I have float x=1.1111 so I can multiple it by 1000 to
>> get 11111 and the preform bitwise like <<2 to get 88888 and then divide
>> by 1000 to go back to float 8.8888. but these seem like "nasty" way to
>> do it. So maybe some of you have great tips?

>Your post has lead to quite a long and rather pointless debate. You
>could help by telling us: What is it actually that you are trying to
>how you could achieve this. Tell us _what_ you want to achieve.

<464e0262\$0\$13207\$(E-Mail Removed)>

Summary: genetic algorithms on encoded operations.

(The OP didn't explain why float was being used instead of an
integral type, though.)
--
"No one has the right to destroy another person's belief by
demanding empirical evidence." -- Ann Landers