473,385 Members | 1,355 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,385 software developers and data experts.

assigning floating literal to void*

if I have the following:
void *x;
const char str[]="abcdefghijklmn";

I can assign x=0x12345678;
I can assign x=str;

but how can I assign a float literal to x such that the content of x is an IEEE754 format of this literal floating point?
Sep 8 '10 #1
18 2590
donbock
2,426 Expert 2GB
So you don't want x to point at a float variable, you want the value of the pointer to coincidentally be the same as some floating-point value.

Zounds! I certainly hope C doesn't let you do that. What do you hope to accomplish?
Sep 8 '10 #2
johny10151981
1,059 1GB
You may have a player with fractional number :)

But You cant have a memory address with fractional number.
Sep 8 '10 #3
Oralloy
988 Expert 512MB
@hschew00,

I think this'll work. Give it a shot...

Expand|Select|Wrap|Line Numbers
  1. assert(sizeof(void *) == sizeof(float));
  2.  
  3. void *x;
  4. float f = 1.23;
  5. *((float *)(void *)&x) = f;
  6.  
  7. *((float *)(void *)&x) = 1.23f;
Sep 8 '10 #4
Oralloy
988 Expert 512MB
@donbock,

C lets you do many, many interesting things.

Just remember - in the end, it's all bits on the bus.

Cheers!
Sep 8 '10 #5
@Oralloy
I realized this is the answer I will get after I posted this, and I think my original intention is not cleared to everybody. Below is a sample that what I want to achieve in embedded ARM7:

Expand|Select|Wrap|Line Numbers
  1. float fval;
  2. int ival;
  3. char sval[100];
  4.  
  5. const STR_INIT[]="ggwegweggegggwgwgw";
  6. enum
  7. {
  8.  DAT_BYTE=0,
  9.  DAT_INT,
  10.  DAT_FLOAT,
  11.  DAT_STRING
  12. };
  13.  
  14. struct PARAMETER
  15. {
  16.  void *value;
  17.  int  data_type;
  18.  void *init;
  19.  void *min;
  20.  void *max;
  21.  void *step;
  22. };
  23. const struct PARAMETER params[] =
  24. {
  25.  {
  26.   &fval,        //*value
  27.   DAT_FLOAT,    //type
  28.   10.0,         //init
  29.   0.0,          //min
  30.   100.0,        //max
  31.   0.5,          //step
  32.  },
  33.  {
  34.   &ival,       //*value
  35.   DAT_INT,     //type
  36.   10,          //init
  37.   0,           //min
  38.   100,         //max
  39.   1,           //step
  40.  },
  41.  {
  42.   sval,        //*value
  43.   DAT_STRING,  //type
  44.   STR_INIT,    //init
  45.   0,           //min
  46.   0,           //max
  47.   0,           //step
  48.  }
  49. };
  50.  
Of course the above example will generate error with visual C compiler due to the first element in params array, where you cannot assign a floating literal to a void* type.
The 2nd and 3rd elements generate warning but that is fine since the results are intended.

Base on the data_type, I can cast the <value>, <init>, <min>, <max>, and <step> to the necessary data type for data manipulation and math operation.

params is declared as const so that it uses Flash memory instead of precious RAM in ARM controller. In actual application, there are well over 200 elements in this params array and the original structure is larger than the example given above.

Another approach will be
Expand|Select|Wrap|Line Numbers
  1. struct PARAMETER
  2. {
  3.  void *value;
  4.  int  data_type;
  5.  float init;
  6.  float min;
  7.  float max;
  8.  float step;
  9. };
Then the 1st and 2nd elements yield the intended results but the compiler generates error on 3rd element because you cannot assign a char* to a float type.

Any idea to get around this?
Sep 9 '10 #6
Oralloy
988 Expert 512MB
@hschew00,

Where there's bits, there's hope. (At least I hope so)

The blighter here is that you want the array statically composed and implemented in ROM (flash), right?

How critical are you on memory? I know that some applications are worse than others, however you can spend considerably more memory in code (not to mention programming time) compensating for structure design, then you spend in data structures.

In this case, we're talking about an extra 800 bytes of data or so in your ROM area. I don't know if that's a deal breaker or no.

First off, can you afford an indirection array? If so, I'd recommend that you just build different structs based on the type and have done with. Or, you can go C++ and actually implement a class hierarchy. But I digress. Besides, this route may cost more than you're willing to spend. I don't know.

Expand|Select|Wrap|Line Numbers
  1. type A element0 = { ... };
  2. type B element1 = { ... };
  3. type A element2 = { ... };
  4. ...
  5. void *params[] = { &element0,
  6.                    &element1,
  7.                    &element2, ... };
Another cheap solution would be to carry an extra word or two around in the structs and have done with. Although this may double the bulk of your data, it's only 16 * 200, or 3200 bytes.

Otherwise you might try something like this and then build it out into your solution, if you find it works:
Expand|Select|Wrap|Line Numbers
  1. assert(sizeof(void *) == sizeof(float));
  2. assert(sizeof(void *) == sizeof(long));
  3.  
  4. void *x;
  5.  
  6. x = (void *)*(long *)(void *)&(1.23f);
I'm sorry I don't have a C++ compiler to test code against, I really don't want to waste your time with possibly dubious suggestions.

Of course you might be best off typing the attributes as unsigned long, so that you can treat them as simple hex values.

All that said, I wish you luck. Also, I'd like to know what your final solution is and the constraints your application is under.

Cheers!
Sep 9 '10 #7
donbock
2,426 Expert 2GB
C99 allows a designator to be used to initialize a union component other than the first one. The following is my initial guess at how to use this feature -- you'll probably have to play around with it before it will compile error-free. (I don't have a C99 compiler to try it out on.)
Expand|Select|Wrap|Line Numbers
  1. union V {
  2.    struct {   /* DAT_BYTE */
  3.       signed char init;
  4.       signed char min;
  5.       signed char max;
  6.       signed char step;
  7.    } bv;
  8.    struct {   /* DAT_INT */
  9.       int init;
  10.       int min;
  11.       int max;
  12.       int step;
  13.    } iv;
  14.    struct {   /* DAT_FLOAT */
  15.       float init;
  16.       float min;
  17.       float max;
  18.       float step;
  19.    } bv;
  20.    const char *sv;   /* DAT_STRING */
  21.    };
  22.  
  23. struct PARAMETER {
  24.    void * const value;
  25.    int data_type;
  26.    union V v;
  27.    };
  28.  
  29. const struct PARAMETER params[] = {
  30.    {
  31.       &fval, //*value
  32.       DAT_FLOAT, //type
  33.       {.fv = {10.0, 0.0, 100.0, 0.5}} // init,min,max,step
  34.    },
  35.    {
  36.       &ival, //*value
  37.       DAT_INT, //type
  38.       {.iv = {10, 0, 100, 1}} // init,min,max,step
  39.    },
  40.    {
  41.       sval, //*value
  42.       DAT_STRING, //type
  43.       {.sv = STR_INIT} // init
  44.    }
  45. };
-------- following added an hour later --------
I see a few ways to improve the preceding design.
  1. Move the value pointer into the union V structures. This allows us to change the type for that field from void* to a pointer to the proper type. This incidentally requires that the sv union field be changed to a structure.
  2. Add a field to the sv structure. This new field contains the size of the value buffer. This provides enough information for access code to protect itself from accessing past the end of the sv value buffer.
  3. Define each of the union V structures separately before the definition of union V. This allows access code of the following form. The benefit is that there is no possibility for a programming error in foo_int() and its peers to cause access to the wrong data_type fields of the PARAMETER.
Expand|Select|Wrap|Line Numbers
  1. foo_int(const struct iv *pi);
  2.  
  3. foo_parameter(const struct PARAMETER *pp) {
  4.    switch (pp->data_type) {
  5.       case DAT_INT:
  6.          foo_int(&pp->v.iv);
  7.          break;
  8.       ...
  9.    }
  10. }
Sep 9 '10 #8
Thanks Donbock. That looks like it may work. I will try that out and post the result. You mentioned C99 has to be used instead of ANSI C (C90??), I may have a problem with the compiler that I got from Keil. I will check that out.
Sep 9 '10 #9
Oralloy
988 Expert 512MB
Don,

Ask an amature (me) get one answer; ask a master (you), get the right answer.

Thanks,
Oralloy!
Sep 9 '10 #10
@Oralloy,
Your solution of different struct for different data type can be another option too. The original structure used in my application is 48bytes instead of 16bytes, moreover, the controller that I used has 16k of RAM only.
Sep 9 '10 #11
Oralloy
988 Expert 512MB
@hschew00,

I know what you're saying. I'm just amazed at the ways in which our tools are evolving to solve our real-world problems. For instance, the selective initializers in C99 as an alternative to overloaded constructors in C++.

The C99 solution is elegant, and very good for statically composing data. The problem with C++ constructors is, of course, that they're dynamic.

I just wish I'd have had selective initialization when I was working on a Rabbit processor building a controller for a destktop instrument in the mid 1990's. It would have made a few of my very interesting (spelled ugly) set-up problems in command and parameter parsing just disappear.

One of the things that interests me is that you've got a problem which fits quite well into the object oriented inheritence model, but which you can't use the (in my mind) appropriate tools. So you're stuck open coding (and maintaining) an objective solution, when you should be solving your problem.

I guess I'm just grousing, because we (as the embedded community) haven't really solved the static initialization problem very well, even as our problems become more complex. We don't seem to deal with dynamic memory very well, either. I just growl at C++ code where all objects must be constructed at program start, and never deleted, although dynamically reusing them is ok. Talk about foolish and frustrating use of the language. Basically writing memory managers that manage fixed pools of objects, not memory. Just because folks are afraid that there might be some magic combination of allocations/deallocations that eats all memory and causes failure. So, instead we have multitude problems with stale references and object pool starvation.

Don has the right of it. Use an enum of separately declared classes, and then treat each class as distinct in your code by using strongly typed pointers. Then you will hopefully avoid all the problems which arise from invalid enum references in your code.

Luck!
Sep 9 '10 #12
donbock
2,426 Expert 2GB
You mentioned C99 has to be used instead of ANSI C (C90??) ...
  • In the beginning, the C language was bestowed by Brian Kernighan and Dennis Ritchie. Now we look back on those halcyon days and call that "K&R C".
  • As time passed, compiler vendors added sundry variations and enhancements.
  • C was first standardized by ANSI in 1989; that same standard was adopted by ISO in 1990. This first standard C is variously referred to as C89 or C90.
  • The ISO standard for C was revised in 1999. This second standard C is referred to as C99.
  • Minor clarifications, corrigendums, and changes have occurred between C90 and C99, but I don't know what names people use for them.
Sep 9 '10 #13
donbock
2,426 Expert 2GB
I guess I'm just grousing, because we (as the embedded community) haven't really solved the static initialization problem very well, even as our problems become more complex.
I've used four strategies for complicated static initialization in my embedded C projects.
  1. Suck it up and do it all by hand. Error-prone, but I can write the initialize code immediately.
  2. Write macros that hide some of the complications. Unfortunately, this only works for not-very complicated initialization.
  3. Implement the initialization with inline tcl code by making use of a generic tcl preprocessor called cpdq that I found in a 1998 Dr. Dobbs article.
  4. Write my own custom preprocessor in perl. Two input files: an invariant perl program I developed, and a specific initialization file that takes the form of perl code. The invariant program is designed to allow the specific initialization to look as much like the logical model of the initialization as possible.
The tcl and cpdq preprocessors have allowed me to add redundancy to collections of static structures in order to improve execution speed without risking inconsistencies in the redundant data.
Sep 9 '10 #14
Don,
I think Visual C 6.0 doesn't like the initialization of union part. i.e.,{.iv = {10, 0, 100, 1}}, same with my Keil Compiler. How would you initialize a static object of a union of different structure types in ANSI C?
Sep 9 '10 #15
Oralloy
988 Expert 512MB
@hschew00

You might try something really, really ugly - a large container class with sequential instances of the specific classes (assuming all they are the same size),
then simply taking the address of the container and treating it as an array...

Expand|Select|Wrap|Line Numbers
  1. struct A{...};
  2. struct B{...};
  3. struct C{...};
  4.  
  5. struct ugly{
  6.   struct A first;
  7.   struct B second;
  8.   struct C third;
  9.   struct A fourth;
  10.   ...
  11. } myArray = { ... };
  12.  
  13. union
  14. {
  15.   struct A a;
  16.   struct B b;
  17.   struct C c;
  18. }
  19. * myArrayPointer = (void *)&myArray;
  20.  
Or is this just too ugly to contemplate?
Sep 9 '10 #16
@Oralloy,
Your solution is way above me. After googling around, realized that ANSI C does not support static initialization for Union, that is a shame. May be I have to give up this approach totally. Thanks to you and Don anyway.
Sep 9 '10 #17
Oralloy
988 Expert 512MB
@hschew00,

My latest solution was to build a monolithic struct with each of the parameter specifications laid out in turn.

Then, I'd point a "parameter pointer" at the structure, and use the memory like it was an array.

Complete and total abuse of the C language.

The idea was to use the containing structure to force the sequential memory layout of each parameter object. Since they are all the same size, they should be laid out correctly, as if in an array.

As I said, complete abuse of the C language. But it should work.

Otherwise you're stuck using ugly casts like the one I wrote in the second example in post #7.

Good luck, man.

Cheers!
Sep 9 '10 #18
donbock
2,426 Expert 2GB
After googling around, realized that ANSI C does not support static initialization for Union, that is a shame.
Not so! It is true that K&R C does not support the use of an initializer with a union type. However, C90 mandated that initializers had to be supported for union types; unfortunately, such initializers have to correspond to only the first element in the union. Then C99 mandated that designators be supported in union initializers so that the initializer value can correspond to any element of the union.

Check your compiler documentation. It should tell you whether or not it is C99-compliant. Look carefully, there may be a option switch that you can throw to activate/deactivate C99 compliance.
Sep 9 '10 #19

Sign in to post your reply or Sign up for a free account.

Similar topics

16
by: BigMan | last post by:
How can I check if assignment of a float to a double (or vice versa) will result in loss of precision?
5
by: Anton Noll | last post by:
We are using Visual Studio 2003.NET (C++) for the development of our software in the fields digital signal processing and numerical acoustics. One of our programs was working correctly if we are...
3
by: Senthilraja | last post by:
I am able to compile the following code and get "hello" as ouput everytime I execute it:- #include <stdio.h> int main (void) { char *str; str="hello"; puts(str); return 0;
15
by: Stig Brautaset | last post by:
Hi group, I'm playing with a little generic linked list/stack library, and have a little problem with the interface of the pop() function. If I used a struct like this it would be simple: ...
7
by: al | last post by:
char s = "This string literal"; or char *s= "This string literal"; Both define a string literal. Both suppose to be read-only and not to be modified according to Standard. And both have...
10
by: Peter Ammon | last post by:
I'm fuzzy on exactly what I can depend on when doing floating point comparisons. I know that calculated values can differ, e.g. I'm not guaranteed that 1. + 2. == 3. What about comparisons with...
26
by: Janice | last post by:
What is the major reason for using void*? When should we use void* for both input arguments and return value? How can we cast the void* pointer to the type we need? Thanx
32
by: ma740988 | last post by:
template <class T> inline bool isEqual( const T& a, const T& b, const T epsilon = std::numeric_limits<T>::epsilon() ) { const T diff = a - b; return ( diff <= epsilon ) && ( diff >= -epsilon );...
10
by: Steve Pope | last post by:
The first of the following functions compiles, the second gives what I think is a spurious error: "cannot convert `const char' to `char *' in assignment". void foo(int m) { char *str; if (m...
2
by: murali.desikan | last post by:
Hi, The definition of floating literal in the C++ (ISO/IEC 14882:2003) grammar is as follows (Note: I have replaced the "opt" subscript used in the standard with to indicate optional symbol)....
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
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: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
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...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
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...

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.