¿Cómo puedo convertir un flotante / doble a ASCII sin usar sprintf o ftoa en C?

¿Cómo puedo convertir un flotante / doble a ASCII sin usar sprintf o ftoa en C?

Estoy usando un sistema embebido

El enfoque que tome dependerá del posible rango de valores. Sin duda, tiene algún conocimiento interno del rango posible y es posible que solo le interesen las conversiones dentro de un rango más estrecho.

Entonces, supongamos que solo está interesado en el valor entero. En este caso, solo asignaría el número a un int o long , en cuyo punto el problema se vuelve bastante obvio.

O suponga que el rango no incluirá ningún exponente grande, pero está interesado en varios dígitos de la fracción. Para obtener tres dígitos de fracción, podría decir int x = f * 1000; , convierta x, y luego inserte el punto decimal como una operación de cadena.

A falta de todo lo anterior, un flotante o doble tiene un bit de signo, una fracción y un exponente. Hay un 1 oculto en la fracción. (Los números se normalizan hasta que no tienen ceros iniciales, momento en el que realizan un cambio más para obtener un poco más de precisión). El número es igual a la fracción (más un ‘1’ inicial) * 2 exponente ** . Básicamente, con todos los sistemas que utilizan la representación IEEE 754, puede utilizar esta página de Wikipedia IEEE 754 para comprender el formato. No es tan diferente de simplemente convertir un número entero.

Para precisión simple, una vez que obtenga el exponente y la fracción, el valor Nota 1 del número es entonces (frac / 2 23 + 1) * 2 exp , o frac * 2 exp – 23 + 2 exp .

Aquí hay un ejemplo que debería comenzar con una conversión útil:

 $ cat tc #include  void xconvert(unsigned frac) { if (frac) { xconvert(frac / 10); printf("%c", frac % 10 | '0'); } } void convert(unsigned i) { unsigned sign, exp, frac; sign = i >> 31; exp = (i >> (31 - 8)) - 127; frac = i & 0x007fffff; if (sign) printf("-"); xconvert(frac); printf(" * 2 ** %d + 2 ** %d\n", exp - 23, exp); printf("\n"); } int main(void) { union { float f; unsigned i; } u; uf = 1.234e9; convert(ui); return 0; } $ ./a.out 1252017 * 2 ** 7 + 2 ** 30 

Nota 1. En este caso, la fracción se está convirtiendo como si el punto binario estuviera a la derecha en lugar de a la izquierda, con ajustes de compensación hechos al exponente y al bit oculto.

 #include void flot(char* p, float x) { int n,i=0,k=0; n=(int)x; while(n>0) { x/=10; n=(int)x; i++; } *(p+i) = '.'; x *= 10; n = (int)x; x = xn; while((n>0)||(i>k)) { if(k == i) k++; *(p+k)='0'+n; x *= 10; n = (int)x; x = xn; k++; } /* Null-terminated string */ *(p+k) = '\0'; } int main() { float x; char a[20]={}; char* p=&a; printf("Enter the float value."); scanf("%f",&x); flot(p,x); printf("The value=%s",p); getchar(); return 0; } 

Incluso en un sistema integrado, sería difícil superar el rendimiento de ftoa. ¿Por qué reinventar la rueda?