bitwise on float

C

Carramba

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?

Thank you in advance!
L R
 
U

user923005

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.
If you want to understand what is going on with the internal format,
then take a look at:

7.12.6.4 The frexp functions
Synopsis
1 #include <math.h>
double frexp(double value, int *exp);
float frexpf(float value, int *exp);
long double frexpl(long double value, int *exp);
Description
2 The frexp functions break a floating-point number into a normalized
fraction and an integral power of 2. They store the integer in the int
object pointed to by exp.
Returns
3 If value is not a floating-point number, the results are
unspecified. Otherwise, the frexp functions return the value x, such
that x has a magnitude in the interval [1/2, 1) or zero, and value
equals x * 2^*exp. If value is zero, both parts of the result are
zero.


7.12.6.6 The ldexp functions
Synopsis
1 #include <math.h>
double ldexp(double x, int exp);
float ldexpf(float x, int exp);
long double ldexpl(long double x, int exp);
Description
2 The ldexp functions multiply a floating-point number by an integral
power of 2. A range error may occur.
Returns
3 The ldexp functions return x * 2^exp.
 
C

Carramba

user923005 skrev:
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. 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 :)
If you want to understand what is going on with the internal format,
then take a look at:

7.12.6.4 The frexp functions
Synopsis
1 #include <math.h>
double frexp(double value, int *exp);
float frexpf(float value, int *exp);
long double frexpl(long double value, int *exp);
Description
2 The frexp functions break a floating-point number into a normalized
fraction and an integral power of 2. They store the integer in the int
object pointed to by exp.
Returns
3 If value is not a floating-point number, the results are
unspecified. Otherwise, the frexp functions return the value x, such
that x has a magnitude in the interval [1/2, 1) or zero, and value
equals x * 2^*exp. If value is zero, both parts of the result are
zero.


7.12.6.6 The ldexp functions
Synopsis
1 #include <math.h>
double ldexp(double x, int exp);
float ldexpf(float x, int exp);
long double ldexpl(long double x, int exp);
Description
2 The ldexp functions multiply a floating-point number by an integral
power of 2. A range error may occur.
Returns
3 The ldexp functions return x * 2^exp.
 
D

Dave Vandervies

user923005 skrev:

neither or... as I stated earlier I need to perform bitwise operation on
float. 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 :)

What Are You Really Trying To Do?

Whatever it is, trying to do bitwise operations on floats is probably
the wrong way to do it.


dave
 
J

John Cochran

user923005 skrev:

neither or... as I stated earlier I need to perform bitwise operation on
float. 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 :)

And like the original responder said, attempting to do bitwise manipulation of
floating point number can't be done.

Now with that said, there are intergral types available in C that have more
bits that may allow you to get the extra precision that you imply you need.
take a look at the long, and long long types.

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,
but instead tell what your actual problem is.

I can illustrate this by something that happened on USENET a long time ago.
Someone asked "How do I sort a list of numbers?" This person received many
different methods and was told the advantages and disadvantages of each
method. Eventually in the thread, someone asked the question "Why do you
want to sort the list of numbers?" He answered "Because I need to find the
smallest number in the list. So if I sort it, I can simply pick the 1st number
in the list after sorting."

So yes, sorting a list of numbers could solve the original posters problem,
but obviously the solution that the poster came up with was sub-optimal to
say the least.
 
W

Walter Roberson

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.
 
C

Clark Cox

user923005 skrev:

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?
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:

new = old * (1<<2);

?
 
R

Richard Heathfield

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

new = old * (1<<2);

?

Only the fact that 1.1111 * (1<<2) is 4.4444. :)
 
C

Carramba

John Cochran skrev:
And like the original responder said, attempting to do bitwise manipulation of
floating point number can't be done.

Now with that said, there are intergral types available in C that have more
bits that may allow you to get the extra precision that you imply you need.
take a look at the long, and long long types.

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,
but instead tell what your actual problem is.

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.

I can illustrate this by something that happened on USENET a long time ago.
Someone asked "How do I sort a list of numbers?" This person received many
different methods and was told the advantages and disadvantages of each
method. Eventually in the thread, someone asked the question "Why do you
want to sort the list of numbers?" He answered "Because I need to find the
smallest number in the list. So if I sort it, I can simply pick the 1st number
in the list after sorting."

there are not only idiots that post on this news group ...
 
C

Carramba

Walter Roberson skrev:
Not to.


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...

thank you
 
C

Carramba

Clark Cox skrev:
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?
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.
 
C

Clark Cox

Clark Cox skrev:

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.
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.
 
U

user923005

Walter Roberson skrev:












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.
 
J

John Cochran

John Cochran skrev:

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.
 
U

user923005

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
 
J

James Dow Allen

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
 
W

Walter Roberson

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.)
 
C

christian.bau

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
achieve? Forget about "bitwise operations", they are just your idea
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?
 
W

Walter Roberson

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
achieve? Forget about "bitwise operations", they are just your idea
how you could achieve this. Tell us _what_ you want to achieve.

The OP already answered this in
<[email protected]>

Summary: genetic algorithms on encoded operations.

(The OP didn't explain why float was being used instead of an
integral type, though.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top