Previous similar questions which didn't answer my question:
bit cast uint64_t to double and back in a macro
Converting uint64_t to Double Value
I need to save a double
to the flash memory on an STM32L476 microcontroller. The flash controller works in 64 bit chunks and the HAL APIs from ST take a uint64_t
parameter for the data to write. To this end, I need to convert the bits from the double variable into one or more uint64_t
s.
I tried the following, which is UB:
uint64_t flash_write_val = *(uint64_t*)&double_value;
However, I get a compiler warning about breaking strict aliasing rules. How would I do this without invoking UB? It doesn't need to be super portable. It can be valid only on a Cortex M4F core.
I'm thinking about this:
union uint64_double {
uint64_t flash_friendly;
double math_friendly;
};
Is this a good approach, or am I still shooting myself in the foot?
只需使用memcpy
将字节复制到您想要的位置。
memcpy(&flash_write_val, &double_val, sizeof(double_val));
It is only Cortex-M3+ answer!!
uint64_t flash_write_val = *(uint64_t*)&double_value;
As Cortex-M3 and newer support not-aligned access the above is 100% safe. I personally prefer memcpy
way, but in FLASH write functions I usually use pointer punning.
union uint64_double {
uint64_t flash_friendly;
double math_friendly;
};
memcpy
function The most portable and and probably most efficient method as modern compilers know very well what memcpy
does and in many cases inline it. uint64_t bar(uint64_t *);
uint64_t foo(double double_val)
{
uint64_t flash_write_val;
memcpy(&flash_write_val, &double_val, sizeof(flash_write_val));
return bar(&flash_write_val);
}
foo:
push {lr}
sub sp, sp, #12
mov r2, r0
mov r3, r1
mov r0, sp
strd r2, [sp]
bl bar
add sp, sp, #12
ldr pc, [sp], #4
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.