Un problema simple, pero no puedo obtener documentación sobre este tipo de formato: quiero imprimir un flotante en una notación científica Fortran, con su parte entera siempre siendo cero.
printf("%0.5E",data); // Gives 2.74600E+02
Quiero imprimirlo así:
.27460E+03
¿Cómo puedo obtener este resultado lo más limpio posible?
Intenté hacer esto con log10()
y pow()
, pero terminé teniendo problemas con los errores de redondeo. Entonces, como comentó @Karoly Horvath , la manipulación de cadenas es probablemente el mejor enfoque.
#include <stdlib.h> char *fortran_sprintf_double(double x, int ndigits) { char format[30], *p; static char output[30]; /* Create format string (constrain number of digits to range 1–15) */ if (ndigits > 15) ndigits = 15; if (ndigits < 1) ndigits = 1; sprintf(format, "%%#.%dE", ndigits-1); /* Convert number to exponential format (multiply by 10) */ sprintf(output, format, x * 10.0); /* Move the decimal point one place to the left (divide by 10) */ for (p=output+1; *p; p++) { if (*p=='.') { *p = p[-1]; p[-1] = '.'; break; } } return output; }
Si solo le importa que la parte entera sea 0
y no omita realmente el 0
, es decir, si está bien con 0.27460E+03
en lugar de .27460E+03
, podría hacer algo similar a esto:
#include <stdio.h> #include <stdlib.h> void fortran_printf(); int main(void) { double num = 274.600; fortran_printf(num); exit(EXIT_SUCCESS); } void fortran_printf(double num) { int num_e = 0; while (num > 1.0) { num /= 10; num_e++; } printf("%.5fE+%02d", num, num_e); }
De lo contrario, debe tomar un desvío sobre las cuerdas. Tenga en cuenta que el código anterior solo está destinado a ayudarlo a comenzar. Ciertamente no maneja ningún caso involucrado.
Un enfoque de manipulación de cadenas:
int printf_NoIntegerPart(double x, int prec) { char buf[20 + prec]; sprintf(buf, "%+.*E", prec - 1, x * 10.0); // use + for consistent width output if (buf[2] == '.') { buf[2] = buf[1]; buf[1] = '.'; } puts(buf); } int main(void) { printf_NoIntegerPart(2.74600E+02, 5); // --> +.27460E+03 }
Esto imprimirá "INF" para |x| > DBL_MAX/10