Parse de ponto flutuante IEEE de dupla precisão em um compilador C sem tipo de precisão dupla
Estou trabalhando com um chip AVR de 8 bits. Não há tipo de dados para um duplo de 64 bits (o dobro apenas mapeia para o flutuador de 32 bits). No entanto, vou receber duplas de 64 bits sobre Serial e preciso gerar duplas de 64 bits sobre Serial.
Como converter o dobro de 64 bits em um flutuador de 32 bits e voltar sem transmiti O formato para os de 32 e 64 bits seguirá o IEEE 754. É claro que assumo uma perda de precisão ao converter para o flutuador de 32 bit
Para converter de float de 64 bits para 32 bits, estou tentando isso:
// Script originally from http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1281990303
float convert(uint8_t *in) {
union {
float real;
uint8_t base[4];
} u;
uint16_t expd = ((in[7] & 127) << 4) + ((in[6] & 240) >> 4);
uint16_t expf = expd ? (expd - 1024) + 128 : 0;
u.base[3] = (in[7] & 128) + (expf >> 1);
u.base[2] = ((expf & 1) << 7) + ((in[6] & 15) << 3) + ((in[5] & 0xe0) >> 5);
u.base[1] = ((in[5] & 0x1f) << 3) + ((in[4] & 0xe0) >> 5);
u.base[0] = ((in[4] & 0x1f) << 3) + ((in[3] & 0xe0) >> 5);
return u.real;
}
Para números como 1.0 e 2.0, o acima funciona, mas quando testei com a passagem de 1.1 como um duplo de 64 bits, a saída foi um pouco menor (literalmente, não é um trocadilho!), Embora isso possa ser um problema com o meu teste. Vejo
// Comparison of bits for a float in Java and the bits for a float in C after
// converted from a 64-bit double. Last bit is different.
// Java code can be found at https://gist.github.com/912636
JAVA FLOAT: 00111111 10001100 11001100 11001101
C CONVERTED FLOAT: 00111111 10001100 11001100 11001100