Floating point number to binary

G

Gaurav Verma

Hi,

I want to convert a floating point number (or a decimal number say
123.456) into binary notation using a C program. Can somebody help me
out with it?

Thanks
Gaurav
 
O

osmium

Gaurav said:
I want to convert a floating point number (or a decimal number say
123.456) into binary notation using a C program. Can somebody help me
out with it?

I don't think it is very clear what you are trying to do. For example, what
do you think the binary representation of a decimal point is? Are you
trying to learn something, as opposed to than actually *doing* something?
If so, what are you trying to learn?
 
B

Brian Gough

I want to convert a floating point number (or a decimal number say
123.456) into binary notation using a C program. Can somebody help me
out with it?

If you want the underlying IEEE representation of a floating point
number you can use a union to access the individual bytes.

e.g. union { double d; struct { unsigned char byte[8]; } ieee ; } u;
 
C

CBFalconer

Brian said:
I want to convert a floating point number (or a decimal number say
123.456) into binary notation using a C program. Can somebody help
me out with it?

If you want the underlying IEEE representation of a floating point
number you can use a union to access the individual bytes.

e.g. union {double d; struct { unsigned char byte[8];} ieee ; } u;

No you can't, at least not portably. What you can do is set up a
pointer to the storage and access it via that.

#include <stdio.h>

int main(void)
{
double d;
unsigned char *p;
unsigned int i;

d = 123.4; /* or whatever */
p = (unsigned char *)(&d);
for (i = 0; i < sizeof(double); i++) {
printf("%2x ", p);
/* do other things with p */
}
putchar('\n');
return 0;
}
 
D

Dan Pop

In said:
Brian said:
I want to convert a floating point number (or a decimal number say
123.456) into binary notation using a C program. Can somebody help
me out with it?

If you want the underlying IEEE representation of a floating point
number you can use a union to access the individual bytes.

e.g. union {double d; struct { unsigned char byte[8];} ieee ; } u;

No you can't, at least not portably.

Care to elaborate on the portability problems of:

union { double d; unsigned char bytes[sizeof(double)]; } u;

?
What you can do is set up a
pointer to the storage and access it via that.

Both aliasing methods are equally blessed by the C standard. And both
are plagued by byte order issues.

C99's %a printf conversion descriptor is the closest solution to the OP's
problem.

Dan
 
B

Ben Pfaff

Brian Gough said:
I want to convert a floating point number (or a decimal number say
123.456) into binary notation using a C program. Can somebody help me
out with it?

If you want the underlying IEEE representation of a floating point
number you can use a union to access the individual bytes.

e.g. union { double d; struct { unsigned char byte[8]; } ieee ; } u;

There's no need to put the array in a structure:
union { double d; unsigned char ieee[8]; } u;
 
B

Ben Pfaff

CBFalconer said:
Brian said:
I want to convert a floating point number (or a decimal number say
123.456) into binary notation using a C program. Can somebody help
me out with it?

If you want the underlying IEEE representation of a floating point
number you can use a union to access the individual bytes.

e.g. union {double d; struct { unsigned char byte[8];} ieee ; } u;

No you can't, at least not portably. What you can do is set up a
pointer to the storage and access it via that.

Assuming IEEE representation is inherently not portable. I don't
think the above union will make the code less portable.
 
C

CBFalconer

Dan said:
CBFalconer said:
Brian Gough wrote:
.... snip ...
If you want the underlying IEEE representation of a floating
point number you can use a union to access the individual bytes.

e.g. union {double d; struct {unsigned char byte[8];} ieee ;} u;

No you can't, at least not portably.

Care to elaborate on the portability problems of:

union { double d; unsigned char bytes[sizeof(double)]; } u;

As I understand it accessing a union member as other than the type
that was stored in it is either implementation or undefined.
 
O

Old Wolf

Brian Gough said:
I want to convert a floating point number (or a decimal number say
123.456) into binary notation using a C program. Can somebody help me
out with it?

If you want the underlying IEEE representation of a floating point
number you can use a union to access the individual bytes.

e.g. union { double d; struct { unsigned char byte[8]; } ieee ; } u;

This is undefined behaviour; to be portable you should go:
unsigned char *ptr = (unsigned char *)&d;
and then access the first (sizeof d) bytes of ptr.

Also note that the size of double is not required to be 8, and it is
not required to use IEEE format (although usually it is).
 
J

Jack Klein

Dan said:
CBFalconer said:
Brian Gough wrote:
... snip ...

If you want the underlying IEEE representation of a floating
point number you can use a union to access the individual bytes.

e.g. union {double d; struct {unsigned char byte[8];} ieee ;} u;

No you can't, at least not portably.

Care to elaborate on the portability problems of:

union { double d; unsigned char bytes[sizeof(double)]; } u;

As I understand it accessing a union member as other than the type
that was stored in it is either implementation or undefined.

....except for unsigned char, which is the one and only bullet proof,
invulnerable type in C. Since unsigned char is the only type required
not to have trap representations, any object that your program has the
right to access, it may access as an array of unsigned chars without
invoking the ever dreaded UB.

See particularly paragraphs 4 and 5 of 6.2.6.1.
 
J

Jack Klein

Brian Gough said:
I want to convert a floating point number (or a decimal number say
123.456) into binary notation using a C program. Can somebody help me
out with it?

If you want the underlying IEEE representation of a floating point
number you can use a union to access the individual bytes.

e.g. union { double d; struct { unsigned char byte[8]; } ieee ; } u;

This is undefined behaviour; to be portable you should go:
unsigned char *ptr = (unsigned char *)&d;
and then access the first (sizeof d) bytes of ptr.

Also note that the size of double is not required to be 8, and it is
not required to use IEEE format (although usually it is).

The union method is neither more nor less portable than the type
punning through the pointer. Any object in C may be accessed as an
array of unsigned character types, this being specifically defined as
its "object representation".
 
D

Dan Pop

In said:
Dan said:
CBFalconer said:
Brian Gough wrote:
... snip ...

If you want the underlying IEEE representation of a floating
point number you can use a union to access the individual bytes.

e.g. union {double d; struct {unsigned char byte[8];} ieee ;} u;

No you can't, at least not portably.

Care to elaborate on the portability problems of:

union { double d; unsigned char bytes[sizeof(double)]; } u;

As I understand it accessing a union member as other than the type
that was stored in it is either implementation or undefined.

As usual, you have difficulties engaging your brain...

In this particular case, the result is implementation-defined for
*exactly* the same reason it is implementation-defined in your suggested
method: the representation of floating point values itself is
implementation-defined.

Aliasing any object by an array of unsigned char is blessed by the
standard, no matter how the aliasing is achieved. See 6.5p7 and its
footnote.

Dan
 
J

Joe Wright

Dan said:
Dan said:
Brian Gough wrote:

... snip ...
If you want the underlying IEEE representation of a floating
point number you can use a union to access the individual bytes.

e.g. union {double d; struct {unsigned char byte[8];} ieee ;} u;

No you can't, at least not portably.

Care to elaborate on the portability problems of:

union { double d; unsigned char bytes[sizeof(double)]; } u;

As I understand it accessing a union member as other than the type
that was stored in it is either implementation or undefined.


As usual, you have difficulties engaging your brain...

In this particular case, the result is implementation-defined for
*exactly* the same reason it is implementation-defined in your suggested
method: the representation of floating point values itself is
implementation-defined.

Aliasing any object by an array of unsigned char is blessed by the
standard, no matter how the aliasing is achieved. See 6.5p7 and its
footnote.

Given float and unsigned int are both 32 bits wide (on my system)..

union {
float f;
unsigned u;
} flt;

flt.f = 1.0;

Now, examining flt.u we find it's 32 bits look like..

00111111 10000000 00000000 00000000

Still as flt.u we split it up to its float components.

Exp = 127 (1)
00000001
Man = .10000000 00000000 00000000

Having assigned to flt.f, does examining flt.u cause problems?
Clearly we are allowed to examine flt as..

unsigned char *ft = (unsigned char *)&flt;

...and examine ft[0] through ft[3] without problem.
 
C

Chris Torek

Given float and unsigned int are both 32 bits wide (on my system)..

union {
float f;
unsigned u;
} flt;

flt.f = 1.0;
[snippage]

Having assigned to flt.f, does examining flt.u cause problems?

Possibly. That it must work, the C Standards sayeth not; and in
fact, at least one implementation (gcc, on SPARC) sometimes seems
to leave the floating point part in a floating point register, and
the integer part in an integer register, and never the twain do
meet. The bits found in flt.u thus have no correspondence to those
underlying flt.f.

Exposing the problem is tricky, as the optimization changes the
machine code if the source code is even sneezed-upon.
Clearly we are allowed to examine flt as..

unsigned char *ft = (unsigned char *)&flt;

..and examine ft[0] through ft[3] without problem.

Yes -- and this did work on that same gcc.
 
L

LM

I don't know any special function for this in C, but it is very easy to do
if you know method of convertion... If you need if, I can describe...
 
P

pete

Gaurav said:
Hi,

I want to convert a floating point number (or a decimal number say
123.456) into binary notation using a C program. Can somebody help me
out with it?

#include <stdio.h>
#include <limits.h>

#define E_TYPE float
#define STRING " %s = %f\n"
#define VALUE 123.456f

typedef E_TYPE e_type;

void bitstr(char *, void const *, size_t);

int main(void)
{
e_type e;
char ebits[CHAR_BIT * sizeof e + 1], *s;

s = STRING;
e = VALUE;
bitstr(ebits, &e, sizeof e);
printf(s, ebits, e);
return 0;
}

void bitstr(char *str, const void *obj, size_t n)
{
unsigned mask;
const unsigned char *byte = obj;

while (n--) {
mask = ((unsigned char)-1 >> 1) + 1;
do {
*str++ = (char)(mask & byte[n] ? '1' : '0');
mask >>= 1;
} while (mask != 0);
}
*str = '\0';
}
 
N

Nicolas Pavlidis

Hi,

I want to convert a floating point number (or a decimal number say
123.456) into binary notation using a C program. Can somebody help me
out with it?

If I understand you right, that you want print out a binary notation of
a floating point number, here is an algorithm that will do this:

1) Divide the number into pre and post comma part
2) Convert each part into a string
3) Print out the two converted parts delimited by a '.'

Here is (one) way to convert a number into a binary representation:

----------8<-------------------snapp------------------------>8----------
char* getBinRep(unsigned char number)
{
char* help;
unsigned char comp_mask = 0x1 << ((sizeof(char) * 8) -1);
char* bin_rep = malloc(sizeof(char) * sizeof(char) * 8 + 1);
if(!bin_rep)
standartErrorHandler(OUT_OF_MEMORY);
help = bin_rep;
while(comp_mask)
{
*help++ = (number & comp_mask) ? '1' : '0';
comp_mask >>= 1;
}
*help = '\0';
return(bin_rep);
}
----------8<-------------------snipp------------------------>8----------

HTH && kind regards,
Nicolas
 
R

Richard Bos

I want to convert a floating point number (or a decimal number say
123.456) into binary notation using a C program. Can somebody help me
out with it?

What, _exactly_, have you got; what, exactly do you want? Have you got a
float in memory, or a string containing "123.456"? Do you want a float
in memory (since all C objects are stored binarily), or do you want a
string containing "1010.1010"?
If you want to go from string to object, use strtod().
If you want to go from object to binary representation in memory, do
nothing; you've already got it.
If you want to go from object to string, that's harder; there is no
built-in printf() specifier for binary as there is for decimal and hex,
so you'll have to roll your own. Keep dividing by two and adding ones or
zeroes depending on the modulus.
If you want to go from decimal representation string to binary
representation string, it's probably easiest to use strtod() first and
then apply the previous solution.

Richard
 
M

Malcolm

Gaurav Verma said:
I want to convert a floating point number (or a decimal number say
123.456) into binary notation using a C program. Can somebody help me
out with it?
Take the second logarithm of the number passed in. This tells you the place
value of the first binary digit.
Set that digit to a 1, then subtract from the passed number. Check for
equality or greater with the power of 2 1 less than the greatest digit. This
tells you if the next binary digit is 1 or zero. If it is 1, subtract.
Continue until the value goes to 0 or infinitesimal (the smallest positive
number representable in your floating point format).
 
K

Keith Thompson

I want to convert a floating point number (or a decimal number say
123.456) into binary notation using a C program. Can somebody help me
out with it?

Your question is ambiguous. What kind of binary representation are
you looking for? Do you want to see the representation of the
floating point number (sign, exponent, mantissa)? Or are you looking
for a binary representation of the mathematical value, something like
"1111011.011110110100" for 123.456?
 

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

No members online now.

Forum statistics

Threads
474,146
Messages
2,570,832
Members
47,374
Latest member
EmeliaBryc

Latest Threads

Top