Pregunta

¿Cómo creo una cadena para que formatee los números de punto flotante para que no tengan puntos o dígitos decimales finales cuando sea un número entero, pero NO cambie a notación científica para números más grandes?

Cuando lo haga:

float myFloat= 15.6f;
float myInt = 5.0f;
float myLarge = 7000000.0f;
sprintf(out, "my float is %g", myFloat);
sprintf(out, "my int is %g", myInt);
sprintf(out, "my large is %g", myLarge);

Me sale algo como:

my float is 15.6
my int is 5
my large is 7e+07f

Quiero todas las cadenas de formato único que darán 15.6, 5 y 700000.

Los comentarios de causa editados no hacen el formato:

Eso es lo que pensé. pero un contenedor es bastante incómodo, ya que las cadenas de formato están incrustadas en cadenas de formato más largas:

sprintf(buf, "%d %g", myInt, myFloat);

¿Cómo envuelves eso?

sprintf(buf, "%d %g", myInt, Wrapper(myFloat));??

¿Qué debería devolver Wrapper? O peor:

sprintf(buf, "%d %s", myInt, Wrapper(myFloat));?? 
¿Fue útil?

Solución

No creo que puedas obtener esto con % g , ya que % g te da el más corto de % e o % f .

Por lo tanto, no creo que haya un solo argumento de printf que lo satisfaga. Para 15.6, puedes usar % 2.1f ; para 7000000, puede utilizar % 7.0f .

Probablemente, lo mejor es escribir una función de envoltura que mire el tamaño de su valor y aplique el argumento correcto printf .

Otros consejos

Puedes formatear con "%. * f " ;, lo que te permite pasar la precisión como un parámetro separado, por ejemplo. sprintf. He usado esto en el pasado cuando quería mostrar 0, 1, 2, o tal vez 3 dígitos muy bien sin extra de 0 al final. Escriba una pequeña función auxiliar que tome el doble / flotante y devuelva una precisión de entero (multiplicando por 1000 y luego haciendo módulo 10, 100, 1000). Luego llame a sprintf con "%. * F " ;, llame a la función auxiliar y pase el flotador.

El enfoque de Mike es razonable, pero puede calcular la cantidad de dígitos directamente usando la función log10, y usar piso o ceil para verificar que, de hecho, tiene un valor entero. Algo como:

#include <math.h>
double x;
...
if (floor(x) == x && x != 0.0) { // x is an non-zero integer value
    int digits = floor(log10(fabs(x)+0.5)) + 1;
    printf("x is %.*f\n", digits, x);
}

Al desempaquetar esa cadena de llamadas a funciones, primero tomamos el valor absoluto para asegurarnos de que el argumento no sea negativo, agregue 0.5 al valor entero conocido para solucionar cualquier posible error de redondeo al calcular el log10 de una potencia exacta de 10 , combine log10 y floor para obtener el exponente de la mayor potencia de 10 menos que fabs (x) +0.5, y finalmente agregue 1 para obtener el número de dígitos necesarios para representar x. Aquí hay algunos valores de muestra (de OpenOffice, pero la función C log10 debería calcularse con una precisión similar):

         x          log10(x+0.5)
         1  0.176091259055681000
         9  0.977723605288848000
        10  1.021189299069940000
        99  1.997823080745730000
       100  2.002166061756510000
       999  2.999782798454140000
      1000  3.000217092972230000
     10000  4.000021714181250000
    100000  5.000002171466980000
   1000000  6.000000217147190000
  10000000  7.000000021714720000
 100000000  8.000000002171470000
1000000000  9.000000000217150000

Reemplace% g con% .10g para mostrar hasta 10 cifras significativas

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top