Using underlying bit representations of floats

H

hammer1234

Hi

I am wondering if there is a way of using the underlying bit
representations of floats. I am interested in creating a violation in
MISRA C:2004 of rule "The underlying bit representations shall not be
used"

I have treid using bitwise operators but these are not compilable.

Is there a way I can use bit representations of floats?
 
J

jacob navia

(e-mail address removed) a écrit :
Hi

I am wondering if there is a way of using the underlying bit
representations of floats. I am interested in creating a violation in
MISRA C:2004 of rule "The underlying bit representations shall not be
used"

I have treid using bitwise operators but these are not compilable.

Is there a way I can use bit representations of floats?
If you use IEEE754 we have:

typedef struct {
unsigned int mantissa1;
unsigned int mantissa0:31;
unsigned int one:1;
unsigned int exponent:15;
unsigned int negative:1;
unsigned int empty:16;
} _longDouble; // 80 bits intel long double
typedef struct {
unsigned int mantissa1;
unsigned int mantissa0:20;
unsigned int exponent:11;
unsigned int sign:1;
} _Double; // 64 bit double

typedef struct {
unsigned int mantissa:23;
unsigned int exponent:8;
unsigned int sign:1;
} _Float; // 32 bit float
 
H

hammer1234

Sorry some typos

Rule 12.12 states "the underlying bit representations of floating type
variables shall not be used"
 
H

hammer1234

Thanks for that can you please explain how this uses the underlying bit
representations of floats/doubles.
 
R

Richard Bos

I am wondering if there is a way of using the underlying bit
representations of floats. I am interested in creating a violation in
MISRA C:2004 of rule "The underlying bit representations shall not be
used"

Of course. Just get a pointer to the float, cast it to unsigned char *,
and treat it as an array of bytes.

The real question is: _why_ would you want to do this, especially since
you'll be violating a rule set you (presumably) use?

Richard
 
R

Richard Bos

jacob navia said:
(e-mail address removed) a écrit :
If you use IEEE754 we have:

_If_. But even then...
typedef struct {
unsigned int mantissa1;
unsigned int mantissa0:31;
unsigned int one:1;
unsigned int exponent:15;
unsigned int negative:1;
unsigned int empty:16;
} _longDouble; // 80 bits intel long double

....you have no guaranteed way of knowing that the implementation will
pack these bitfields the way you think they'll be packed, and...
typedef struct {
unsigned int mantissa1;
unsigned int mantissa0:20;
unsigned int exponent:11;
unsigned int sign:1;
} _Double; // 64 bit double

....you are to keep your grubby little fingers _off_ identifiers starting
with an underline and a capital letter. Those are for the implementation
to declare, not for you.

Richard
 
H

hammer1234

Thanks. I am trying to create some test cases violating rules to
evaluate how sucessful certain static code checking tools are in
detecting rule violations.

Thanks I will give it a go
 
I

Ian Collins

Hi

I am wondering if there is a way of using the underlying bit
representations of floats. I am interested in creating a violation in
MISRA C:2004 of rule "The underlying bit representations shall not be
used"

I have treid using bitwise operators but these are not compilable.

Is there a way I can use bit representations of floats?
Why?

The best (worst?) you can do is cast a pointer to float to a pointer to
some integer type of the same size (assuming there is one) and play with
the bits that way. Very non-standard.
 
J

jacob navia

Richard Bos a écrit :
_If_. But even then...




...you have no guaranteed way of knowing that the implementation will
pack these bitfields the way you think they'll be packed, and...




...you are to keep your grubby little fingers _off_ identifiers starting
with an underline and a capital letter. Those are for the implementation
to declare, not for you.

Richard
No guarantees. This is not production code. The underscored identifiers
are easily explained: I took them from the lcc-win32 headers, and they
are part od the lcc-win32 implementation.

Probably in other machines this needs to be adjusted accordingly. The
code here gives just a way of doing it in a particular machine. Up to
the OP to adapt this to his environment

jacob
 
H

hammer1234

Ok, I know this is something that should never be used. It is jsut a
test case. Is this along the right lines??

typedef float T_FLOAT;
typedef int T_INT;
typedef unsigned int T_UINT;

T_INT main(T_INT a)
{


T_UINT w=0U;
T_UINT *x=0;
T_FLOAT *y=0;
T_FLOAT aa=1.0;
T_UINT z=1U;
T_UINT bb=0U;
T_UINT cc=5U;

y=&aa; /* Assign y the address of aa*/

x=(T_UINT *)y; /* assign x the address of y (a float)*/

z=(*x); /*assign z the value stored in x*/

bb=z&cc; /*Using the bits of a floating point value*/

return(a);

}
 
I

Ian Collins

Ok, I know this is something that should never be used. It is jsut a
test case. Is this along the right lines??
Yes, assuming sizeof(float) == sizeof(int) on your system.

Those typedefs are rather horrible, try the C99 types if they exist on
your platform.
 
S

santosh

Ok, I know this is something that should never be used. It is jsut a
test case. Is this along the right lines??

typedef float T_FLOAT;
typedef int T_INT;
typedef unsigned int T_UINT;

Portable as well as standard typedefs for these, (and more), are
available in the header stdint.h as of C99. You can use those if your
implementation supports them.
T_INT main(T_INT a)

This is not a standard declaration of main(). As per C99 main() can
only have the forms int main(void) or int main(int, char **).
{
T_UINT w=0U;
T_UINT *x=0;
T_FLOAT *y=0;
T_FLOAT aa=1.0;
T_UINT z=1U;
T_UINT bb=0U;
T_UINT cc=5U;

y=&aa; /* Assign y the address of aa*/

x=(T_UINT *)y; /* assign x the address of y (a float)*/

z=(*x); /*assign z the value stored in x*/

The brackets around x are not necessary:
z = *x;
bb=z&cc; /*Using the bits of a floating point value*/

return(a);

You return a variable you haven't declared.
Also return a; would be a better form.
 
H

hammer1234

santosh said:
Portable as well as standard typedefs for these, (and more), are
available in the header stdint.h as of C99. You can use those if your
implementation supports them.


This is not a standard declaration of main(). As per C99 main() can
only have the forms int main(void) or int main(int, char **).


The brackets around x are not necessary:
z = *x;


You return a variable you haven't declared.
Also return a; would be a better form.



Unfortunately misra c:2004 states that C90 must be used.
 
H

hammer1234

Ian said:
Yes, assuming sizeof(float) == sizeof(int) on your system.

Those typedefs are rather horrible, try the C99 types if they exist on
your platform.




Better??

typedef float float32_t;
typedef unsigned int uint32_t;

uint32_t main(void)
{
uint32_t *x=0;
float32_t *y=0;
float32_t aa=1.0f;
uint32_t z=1U;
uint32_t bb=0U;
uint32_t cc=5U;

y=&aa; /* Assign y the address of aa*/

x=(uint32_t *)y; /* assign x the address of y (a float)*/

z=*x; /*assign z the value stored in x*/

/*The value of z is 1065353216 */

bb=(z&cc); /*Using the bits of a floating point value*/
/*bb equals zero*/

return(bb);

}
 
C

CBFalconer

jacob said:
Richard Bos a écrit :

No guarantees. This is not production code. The underscored
identifiers are easily explained: I took them from the lcc-win32
headers, and they are part od the lcc-win32 implementation.

So what? This is c.l.c, and particular implementations are not of
interest. At the very least you should have modified the
identifiers.
Probably in other machines this needs to be adjusted accordingly.
The code here gives just a way of doing it in a particular machine.
Up to the OP to adapt this to his environment

So you should have said so in your original answer, instead of
leaving such misinformation lying about to trap the unwary. You of
all people should know better.

--
"The power of the Executive to cast a man into prison without
formulating any charge known to the law, and particularly to
deny him the judgement of his peers, is in the highest degree
odious and is the foundation of all totalitarian government
whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
 
C

CBFalconer

Thanks for that can you please explain how this uses the underlying bit
representations of floats/doubles.

Thanks for what? What is 'this'? Usenet articles may or may not
be delivered to the reader, and even if they have been, they may
not be conveniently available. Thus every article has to stand on
its own, and requires suitable context inclusion. See my sig.
below and the referenced URLs for means to do this on the foul
broken google interface to usenet.

--
"The power of the Executive to cast a man into prison without
formulating any charge known to the law, and particularly to
deny him the judgement of his peers, is in the highest degree
odious and is the foundation of all totalitarian government
whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
 
K

Keith Thompson

santosh said:
Portable as well as standard typedefs for these, (and more), are
available in the header stdint.h as of C99. You can use those if your
implementation supports them.

Not really. C99's stdint.h does provide typedefs that specify the
sizes of integer types (but not for floating-point types). But the
above typedefs merely provide obscure aliases for the predefined
types.

Drop the typedefs, and change all occurrences of "T_FLOAT" to "float",
etc.
 
P

pete

Hi

I am wondering if there is a way of using the underlying bit
representations of floats. I am interested in creating a violation in
MISRA C:2004 of rule "The underlying bit representations shall not be
used"

I have treid using bitwise operators but these are not compilable.

Is there a way I can use bit representations of floats?

Not portably.
But if you don't want to write portable code,
maybe you can take a look at one representation,
and write code for that.


/* BEGIN bitstr.c */

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

#define STRING "%f = %s\n"
#define E_TYPE float
#define P_TYPE double
#define INITIAL .51f
#define FINAL 3
#define INC(E) ((E) *= 2)

typedef E_TYPE e_type;
typedef P_TYPE p_type;

void bitstr(char *str, const void *obj, size_t n);

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

puts("\n/* BEGIN output from bitstr.c */\n");
e = INITIAL;
bitstr(ebits, &e, sizeof e);
printf(STRING, (p_type)e, ebits);
while (FINAL > e) {
INC(e);
bitstr(ebits, &e, sizeof e);
printf(STRING, (p_type)e, ebits);
}
puts("\n/* END output from bitstr.c */");
return 0;
}

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

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

/* END bitstr.c */
 
M

Me

typedef float float32_t;
typedef unsigned int uint32_t;

uint32_t main(void)

"It shall be defined with a return type of int"
{
uint32_t *x=0;
float32_t *y=0;
float32_t aa=1.0f;
uint32_t z=1U;
uint32_t bb=0U;
uint32_t cc=5U;

y=&aa; /* Assign y the address of aa*/

Let me guess, all your programming teachers took points off for not
commenting like this?
x=(uint32_t *)y; /* assign x the address of y (a float)*/

z=*x; /*assign z the value stored in x*/

Undefined due to aliasing.
/*The value of z is 1065353216 */

bb=(z&cc); /*Using the bits of a floating point value*/
/*bb equals zero*/

return(bb);

}

What you're doing is highly implementation dependent anyway so I'm not
going to bother to nitpick if unsigned int doesn't have the same
size/alignment as float or if unsigned int has any trap representations
but I will say that the only correct way to do the above is to
basically use:

float f = whatever;
unsigned int in;
assert(sizeof(f) == sizeof(in));
memcpy(&in, &f, sizeof(f));

or the following:

float f = whatever;
unsigned char *cp = (unsigned char*)&f;
for (size_t i = 0; i != sizeof(f); ++i) {
do_something_with(cp);
}

which is the only way guaranteed not to do anything undefined by the
standard but since you need to know how the bits are laid out anyway
and it's really annoying messing with the float bits as unsigned
char[sizeof(float)], I'd probably stick with the first one (but with
the unsigned int typedeffed as floatbits_t or something).
 

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,176
Messages
2,570,947
Members
47,498
Latest member
log5Sshell/alfa5

Latest Threads

Top