473,386 Members | 1,830 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

converting floating point number to byte array in C

Hi all,
I am trying a program to convert floating point values to a byte array
and printing the same to the screen.The idea behind this is we already
have an existing function which can do byte level parsing what ever
may be the type of data.The data would be coming from an external
environment.When I parse int,char at byte level,I get right
values,where as floating point just prints 0.000000 to the
screen.Given below is a sample program I tried:

#include <stdio.h>
struct info
{
unsigned char day;
unsigned char month;
unsigned short year;
unsigned char arr[6];
float data;
};
struct info info1;
struct info info2;
void parser(unsigned char* data);

int main(int argc, char *argv[])
{
info1.day=31;
info1.month=8;
info1.year=2016;
info1.arr[0]='h';
info1.arr[1]= 'a';
info1.arr[2]= 'i';
info1.data=12345.50;
printf("data is %f\n",info1.data);
printf("size of info struct is %d\n",sizeof(info));
parser((unsigned char*)(&info1));

return 1;
}
void parser(unsigned char* data)
{
int i;
info2.day=data[0];
info2.month=data[1];
info2.year=(data[3]<<8)|(data[2]);
#if 0
for(i=0;i<10;i++)
{
printf("subsequent value in array is %d
\n",data[i]);
}

#endif
for(i=4;data[i]!='\0';i++)
{
printf("character in arr is %c\n",data[i]);
}
printf("data in arr is %c\n",data[4]);
printf("data in arr is %c
\n",data[5]);
printf("data in arr is %c\n",data[6]);
info2.data=(float)((data[10]<<24)|(data[9]<<16)|(data[8]<<8)|
(data[7]));
printf("day is %d\n",info2.day);
printf("month is %d\n",info2.month);
printf("year is %d\n",info2.year);
printf("data is %f\n",info2.data);
}

I get correct values for all the variables with in info2 struct except
for info2.data.
info2.data,prints 0.000000 in the screen,where as assigned value is
12345.50.

Where have I done mistake?I tried searching in net and this groups,but
nothing seems explainative enough for me to understand.
Can someone help me to correct this and give me a sample program
showing how to convert floating point values to bytes in C?Any links
are also appreciated.

Looking farward for your replies and advanced thanks for the same,
Regards,
s.subbarayan
Aug 18 '08 #1
9 5135
ssubbarayan <ss****@gmail.comwrote:
I am trying a program to convert floating point values to a byte array
and printing the same to the screen.The idea behind this is we already
have an existing function which can do byte level parsing what ever
may be the type of data.The data would be coming from an external
environment.When I parse int,char at byte level,I get right
values,where as floating point just prints 0.000000 to the
screen.Given below is a sample program I tried:
#include <stdio.h>
struct info
{
unsigned char day;
unsigned char month;
unsigned short year;
unsigned char arr[6];
float data;
};
struct info info1;
struct info info2;
void parser(unsigned char* data);
int main(int argc, char *argv[])
{
info1.day=31;
info1.month=8;
info1.year=2016;
info1.arr[0]='h';
info1.arr[1]= 'a';
info1.arr[2]= 'i';
info1.data=12345.50;
printf("data is %f\n",info1.data);
printf("size of info struct is %d\n",sizeof(info));
This should be

printf("size of info struct is %d\n",sizeof(struct info));

or

printf("size of info struct is %d\n",sizeof info1 );

or it won't compile.
parser((unsigned char*)(&info1));
return 1;
}
void parser(unsigned char* data)
{
int i;
info2.day=data[0];
info2.month=data[1];
info2.year=(data[3]<<8)|(data[2]);
#if 0
for(i=0;i<10;i++)
{
printf("subsequent value in array is %d
\n",data[i]);
}
#endif
for(i=4;data[i]!='\0';i++)
{
printf("character in arr is %c\n",data[i]);
}
printf("data in arr is %c\n",data[4]);
printf("data in arr is %c
\n",data[5]);
printf("data in arr is %c\n",data[6]);
info2.data=(float)((data[10]<<24)|(data[9]<<16)|(data[8]<<8)|
(data[7]));
printf("day is %d\n",info2.day);
printf("month is %d\n",info2.month);
printf("year is %d\n",info2.year);
printf("data is %f\n",info2.data);
}
I get correct values for all the variables with in info2 struct except
for info2.data.
info2.data,prints 0.000000 in the screen,where as assigned value is
12345.50.
Where have I done mistake?I tried searching in net and this groups,but
nothing seems explainative enough for me to understand.
There are several thinbs broken with your approach. First of all
you don't consider that the compiler could insert any amount of
padding bytes between the elements of the structure. That it
seem to work is no proof that it's correct - things can easily
stop to work when you use a different platform (or maybe just a
different compiler).

Second, if you really want to use external data instead data
generated by your program there's the problem with different
endianness and different sizes of types. So, unless you use
only data from a machine with the same architecture it also
will break for integer data types.

Another assumption you make is that all machines use the same
encoding for characters. While this is probably true for 99%
of all machines it is not a given.

Finally
info2.data=(float)((data[10]<<24)|(data[9]<<16)|(data[8]<<8)|(data[7]));
is really strange. Even if there would be no padding in the
structure etc. and you have 2 byte shorts then the data
element of the structure starts at byte 10 and uses this and
the following bytes, not the ones before.

Then what you're doing here is make an integer out of the bytes
and then store that integer value in a float variable - the cast
is completely redundant. If the data element of the structure
really starts at position 10 then you would have to use

info2.data = * ( float * ) ( data + 10 );

to get it right. This tells the compiler that 'data + 10' is
the address where a float is and to dereference this address
and store the value in info2.data.

Again, if you're using "external data", i.e. data generated on
a different machine you have a very good chance that this will
fail. Same for the case that the compiler had to insert padding
bytes.
Can someone help me to correct this and give me a sample program
showing how to convert floating point values to bytes in C?Any links
are also appreciated.
You can't reliably unless you know exactly all the details how
data are stored on the machine that created the data, how many
padding bytes the compiler inserts on that machine etc. Instead
of doing such dirty tricks (and probably getting it right only
for a small fraction of the possible cases better use a scheme
to store and read data in a unique format. Simplest thing is
probably to convert everything to ASCII strings and work with
those.

You may also have a look at RPC (Remote Procedure Call) and the
external data representation (XDR) used there to "serialize"
the data . But, as far as I remember, even that doesn't deal
with floating point numbers...

Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
Aug 18 '08 #2
Jens Thoms Toerring wrote:
This should be

printf("size of info struct is %d\n",sizeof(struct info));

or

printf("size of info struct is %d\n",sizeof info1 );

or it won't compile.
In C89, a cast should be used
when one of the arguments to printf is a size_t type.

printf("size of info struct is %d\n", (int)sizeof info1 );

or

printf("size of info struct is %u\n", (unsigned)sizeof info1 );

or

printf("size of info struct is %lu\n",
(long unsigned)sizeof info1 );

--
pete
Aug 18 '08 #3
On Aug 18, 7:02 pm, pete <pfil...@mindspring.comwrote:
Jens Thoms Toerring wrote:
This should be
printf("size of info struct is %d\n",sizeof(struct info));
or
printf("size of info struct is %d\n",sizeof info1 );
or it won't compile.

In C89, a cast should be used
when one of the arguments to printf is a size_t type.
It is indeed so.
printf("size of info struct is %d\n", (int)sizeof info1 );
Don't use that.
or

printf("size of info struct is %u\n", (unsigned)sizeof info1 );
That's okay.
or

printf("size of info struct is %lu\n",
(long unsigned)sizeof info1 );
That's even better, since in C89, ULONG_MAX is the largest integer.

What I'd do

#if __STDC_VERSION__ == 199901L
# define x(z) z
# define PRIzINT "zu"
#else
# define x(z) (unsigned long)z
# define PRIzINT "lu"
#endif

size_t n;

/* ... */

printf("n = %" PRIzINT "\n", x(n));
Aug 18 '08 #4
On Mon, 18 Aug 2008 10:41:52 -0700 (PDT), vi******@gmail.com wrote:
>On Aug 18, 7:02 pm, pete <pfil...@mindspring.comwrote:
>Jens Thoms Toerring wrote:
This should be
printf("size of info struct is %d\n",sizeof(struct info));
or
printf("size of info struct is %d\n",sizeof info1 );
or it won't compile.

In C89, a cast should be used
when one of the arguments to printf is a size_t type.

It is indeed so.
> printf("size of info struct is %d\n", (int)sizeof info1 );

Don't use that.
Since the structure in question is obviously less than 100 bytes long,
why not?
>
>or

printf("size of info struct is %u\n", (unsigned)sizeof info1 );

That's okay.
>or

printf("size of info struct is %lu\n",
(long unsigned)sizeof info1 );

That's even better, since in C89, ULONG_MAX is the largest integer.

What I'd do

#if __STDC_VERSION__ == 199901L
# define x(z) z
# define PRIzINT "zu"
#else
# define x(z) (unsigned long)z
# define PRIzINT "lu"
#endif

size_t n;

/* ... */

printf("n = %" PRIzINT "\n", x(n));
--
Remove del for email
Aug 18 '08 #5
On Mon, 18 Aug 2008 07:32:23 -0700 (PDT), ssubbarayan
<ss****@gmail.comwrote:
>Hi all,
I am trying a program to convert floating point values to a byte array
and printing the same to the screen.The idea behind this is we already
snip
info2.data=(float)((data[10]<<24)|(data[9]<<16)|(data[8]<<8)|
(data[7]));
snip
>I get correct values for all the variables with in info2 struct except
for info2.data.
info2.data,prints 0.000000 in the screen,where as assigned value is
12345.50.
A way to do it is
I:\c16>type ba1.c
#include <stdio.h>

int main() {
float f = 12345.5;
unsigned char *p = (unsigned char *)&f;
union {
float f;
unsigned char c[4];
} cf;

cf.c[0] = *p;
cf.c[1] = *(p + 1);
cf.c[2] = *(p + 2);
cf.c[3] = *(p + 3);

printf("%f\n", cf.f);

return 0;
}
I:\c16>tcc ba1.c
Turbo C Version 2.01 Copyright (c) 1987, 1988 Borland International
ba1.c:
Turbo Link Version 2.0 Copyright (c) 1987, 1988 Borland
International

Available memory 395354
I:\c16>ba1
12345.500000

I:\c16>
Aug 19 '08 #6
On 18 Aug, 16:26, j...@toerring.de (Jens Thoms Toerring) wrote:

<snip>
You may also have a look at RPC (Remote Procedure Call) and the
external data representation (XDR) used there to "serialize"
the data . But, as far as I remember, even that doesn't deal
with floating point numbers...
you remember incorrectly

http://www.faqs.org/rfcs/rfc1014.html

(RFC 1014 is XDR)

There is both a float and a double type
--
Nick Keighley

Aug 19 '08 #7
vi******@gmail.com writes:
On Aug 18, 7:02 pm, pete <pfil...@mindspring.comwrote:
[...]
>In C89, a cast should be used
when one of the arguments to printf is a size_t type.

It is indeed so.
> printf("size of info struct is %d\n", (int)sizeof info1 );

Don't use that.
It's not unreasonable to use int when you're sure the size is no more
than 32767 bytes.
>or

printf("size of info struct is %u\n", (unsigned)sizeof info1 );

That's okay.
Ok, that takes you up to 65535 bytes. Why is that significantly
better than 32767?
>or

printf("size of info struct is %lu\n",
(long unsigned)sizeof info1 );

That's even better, since in C89, ULONG_MAX is the largest integer.
Yes, that's the most general C89/C90-compatible way to do it.
What I'd do

#if __STDC_VERSION__ == 199901L
# define x(z) z
# define PRIzINT "zu"
#else
# define x(z) (unsigned long)z
# define PRIzINT "lu"
#endif

size_t n;

/* ... */

printf("n = %" PRIzINT "\n", x(n));
First, I'd use
#if __STDC_VERSION__ >= 199901L
rather than
#if __STDC_VERSION__ == 199901L

And I wouldn't go to all that trouble unless I was seriously worried
about the size of that particular thing exceeding ULONG_MAX bytes.
The best C90 solution:

printf("The size is %lu\n", (unsigned long)sizeof whatever);

is also a perfectly reasonable C99 solution most of the time, and it
has the advantage of not forcing the reader to figure out what x() and
PRIzINT mean. (And in any case, I wouldn't call that macro "x"; I'd
at least pick an all-caps name.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 22 '08 #8
On Aug 22, 7:38 pm, Keith Thompson <ks...@mib.orgwrote:
vipps...@gmail.com writes:
On Aug 18, 7:02 pm, pete <pfil...@mindspring.comwrote:
[...]
In C89, a cast should be used
when one of the arguments to printf is a size_t type.
It is indeed so.
printf("size of info struct is %d\n", (int)sizeof info1 );
Don't use that.

It's not unreasonable to use int when you're sure the size is no more
than 32767 bytes.
or
printf("size of info struct is %u\n", (unsigned)sizeof info1 );
That's okay.

Ok, that takes you up to 65535 bytes. Why is that significantly
better than 32767?
If the value of the sizeof expression is out of range, the cast will
invoke undefined behavior or implementation defined behavior. I don't
remember which, but I'm going to read some previous messages of mine
asking that question.

<snip>
The best C90 solution:

printf("The size is %lu\n", (unsigned long)sizeof whatever);

is also a perfectly reasonable C99 solution most of the time, and it
has the advantage of not forcing the reader to figure out what x() and
PRIzINT mean. (And in any case, I wouldn't call that macro "x"; I'd
at least pick an all-caps name.)
I called it x just for the example ;)
Aug 23 '08 #9
vi******@gmail.com writes:
On Aug 22, 7:38 pm, Keith Thompson <ks...@mib.orgwrote:
>vipps...@gmail.com writes:
On Aug 18, 7:02 pm, pete <pfil...@mindspring.comwrote:
[...]
>In C89, a cast should be used
when one of the arguments to printf is a size_t type.
It is indeed so.
> printf("size of info struct is %d\n", (int)sizeof info1 );
Don't use that.

It's not unreasonable to use int when you're sure the size is no more
than 32767 bytes.
>or
> printf("size of info struct is %u\n", (unsigned)sizeof info1 );
That's okay.

Ok, that takes you up to 65535 bytes. Why is that significantly
better than 32767?

If the value of the sizeof expression is out of range, the cast will
invoke undefined behavior or implementation defined behavior. I don't
remember which, but I'm going to read some previous messages of mine
asking that question.
[...]

Ah, yes, good point.

A conversion to a signed type yields an implementation-defined result
(or, in C99, may raise an implementation-defined signal) if the value
cannot be represented in the target type.

A conversion to an unsigned type yields a well defined result (though
if it's out of range it won't be particularly meaningful in this
case).

If you really want to be paranoid, you can write a routine to print a
size_t value; it can check whether the value will fit in an unsigned
long before attempting to print it. Or you can just write the code to
generate a decimal string representing the value. (I'm thinking of
the possibility of a partial C99 implementation that has size_t bigger
than unsigned long, but that doesn't support "%zu"; since the compiler
and runtime library are sometimes from different vendors, this isn't
entirely implausible.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 23 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Dan E. | last post by:
Hi All, If I have an 8-byte floating point number in hex how do I convert it to a double? 0 0 0 0 0 98 C1 3F this should be about .13746 Thanks Dan...
25
by: Gaurav Verma | last post by:
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 --...
9
by: Steven D'Aprano | last post by:
I'm looking for some way to get the next floating point number after any particular float. (Any mathematicians out there: I am aware that there is no "next real number". But floats are not real...
8
by: vendredi5h | last post by:
Hello all, I'd like to split a 64-bits word (hold as a floating point number) into two 32-bits words (hold as integers). Bitwise operators are working on Integers, not on floating point. ...
2
by: laila | last post by:
Hello, I'm a newbie at C and i have a problem:) I tried to solve this by using for. but i couldnt. the program should read a floating point number from the user character by character until the...
14
by: mathieu | last post by:
hi there, I do not understand the syntax for ios_base::precision. Let say I have a floating point: const float f = 0.313244462; How do I write is to a stream ? const float f =...
7
by: ma740988 | last post by:
Consider the equation (flight dynamics stuff): Yaw (Degrees) = Azimuth Angle(Radians) * 180 (Degrees) / 3.1415926535897932384626433832795 (Radians) There's a valid reason to use single...
2
by: avais | last post by:
I am transmitting a numer over a uart and reading the number in Matlab by using fread function. To transmit a number that occupies more than byte. I use and operation to access the individual bytes...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.