Hello,
how can I achieve
long l = WHAT_EVER_MACRO (-12.5); main() { printf("%X",l); }
resulting in output "0xC1480000" the binary representation of the float -12.5 . Without that MACRO the value is 0xFFFFFFF4 = -12 for integers .
Because of given circumstances in an existing project I have to store float values during initialization in long variables.
Is there any possibility?
Thanks in advance
Jürgen
"I don't see why you need the "type" information, and why you think it will help maintain data integrity / validity."
Think about it. Storing a type field isn't meaningful when a union is used for instant assign/read out, and with the special case that the two data types in the union are expected to be same size and just represent a form of type cast.
But when data is stored in a union in one section of the code and processed in other sections, it is avery common error that a developer assumes that a union contains data of one format, while it is actually containing data of another format. A union is very often used not as type converter but to allow multiple variables to reuse the same memory space in which case it is important to know if the union contain valid data or not.
"it is avery common error that a developer assumes that a union contains data of one format, while it is actually containing data of another format."
1) it sounds like a case of human error and no amount of inclusion of "type" data can prevent developers from writing stupid code. 2) that particular case isn't relevant here.
"A union is very often used not as type converter but to allow multiple variables to reuse the same memory space in which case it is important to know if the union contain valid data or not."
I am not sure about that one. I have to confess that I rarely (never?) used union as a way to reuse space - the compiler does a better job than I do there - and I use unions extensively to as a way to shift data fast.
1) The inclusiion of a type field means that the source code can test this fieald to verify what data is there.
function get_calibration(my_union) { if (my_union.type != TYPE_CALIBRATION) return NULL; else return my_union.fancy_calibration; }
2) Irrelevant if something may not be needed in this case. People will still regularly come and revisit threads at a later time. Then it is helpful to mention the use of a 'type' field to let people remember what contents that are used in the union.
"I am not sure about that one. I have to confess that I rarely (never?) used union as a way to reuse space - the compiler does a better job than I do there - and I use unions extensively to as a way to shift data fast."
But union as type converters are still just one usage alternative.
They are quite often used in C code for abstraction, to create polymorphic objects. A device may support multiple different sensor types. So it might be useful to combine all the information into generic methods.
function get_measurement(sensor) { switch (sensor.type) { case TYPE_TEMP: sprintf(res,"%u.%u C",sensor.val.temp.value/10,sensor.val.temp.value%10); break; case TYPE_VOLT: v = sensor.val.volt.value; v += sensor.val.volt.offset; v *= sensor.val.volt.scale; if (sensor.val.volt.scale >= 1000) sprintf(res,"%u V",v); else sprintf(res,"%u.%03u V",v/1000,v%1000); break; case TYPE_ENERGY: v = sensor.val.energy.value; if (sensor.val.energy.high_gain) { v /= 10; sprintf(res,"%u.%u Ah",v/10,v%10); } else { sprintf(res,"%u2u mAh",v); } break; case TYPE_LIGHT: sprintf(res,"%u lx",normalize_to_lux(&sensor.val.light); break; default: // Unused sensor position. strcpy(res,"-"); } switch (sensor.if_type) { case IF_ONEWIRE: strcat(res,", addr:"); format_onewire_addr(res+strlen(res),sensor.addr.onewire); break; case IF_ETH: strcat(res,", addr:"); format_ip_addr(res+strlen(res),sensor.addr.ip); break; } return res; }
The original reason for unions (they exists in quite a number of languages) is for polymorphic use - not for type conversion. It's just that for low-level programming, they are very much liked as for type conversion.
"But union as type converters are still just one usage alternative."
sure.
"So it might be useful to combine all the information into generic methods."
it "might". I was just objecting to the notion that a union is very often used to share space, based on my experience.
I didn't say that it is NOT helpful to include type information in any application.
"I was just objecting to the notion that a union is very often used to share space, based on my experience."
But that would obviously depend on: - how many different types of programs you have looked at. - how many different developers who have designed the programs. - how many different types of platforms. - ...
The use of unions for polymorphic objects obviously happens more when writing object-oriented programs in C. But object-oriented programs tends to expect object pointers. And the 8051 is lousy with indexing around pointers making it a very expecnsive concept for the 8051 architecture. Lots of other architectures are great at handling pointer+offset addressing but have had to wait lots of years for a [good] C++ compiler.
"I didn't say that it is NOT helpful to include type information in any application."
So why did you write "and why you think it will help maintain data integrity / validity." instead of something like: "But in this case, the union is used as a temporary and lives for such a short time, that there is no need to flag it as used or what type that was originally assigned"?
"But that would obviously depend on:"
sure. but why is it relevant here?
"So why did you write "and why you think it will help maintain data integrity / validity.""
because I presumed that we were talking about THIS PARTICULAR case in this very discussion, not ALL cases.
maybe that's an assumption not applicable to you guys?