¿Cuál es la manera más fácil para truncar un C++ float variable que tiene un valor de 0.6000002 a un valor de 0.6000 y almacenar en la variable?

OriginalEl autor BeachRunnerFred | 2008-11-20

9 Comentarios

  1. 7

    Primer lugar, es importante saber que los números de punto flotante son aproximados. Ver el enlace proporcionado por @Greg Hewgill para entender por qué este problema no es totalmente solucionable.

    Pero aquí hay un par de soluciones para el problema que probablemente va a satisfacer su necesidad:

    Probablemente el mejor método, pero menos eficientes:

    char sz[64];
    double lf = 0.600000002;
    sprintf(sz, "%.4lf\n", lf); //sz contains 0.6000
    
    double lf2 = atof(sz);
    
    //lf == 0.600000002;
    //lf2 == 0.6000
    
    printf("%.4lf", lf2); //print 0.6000

    La manera más eficiente, pero probablemente menos precisa:

    double lf = 0.600000002;
    int iSigned = lf > 0? 1: -1;
    unsigned int uiTemp = (lf*pow(10, 4)) * iSigned; //Note I'm using unsigned int so that I can increase the precision of the truncate
    lf = (((double)uiTemp)/pow(10,4) * iSigned);

    OriginalEl autor Brian R. Bondy

  2. 6

    Realismo que no es posible. No es un C++ limitación, pero sólo la forma de punto flotante de obras. Para muchos de los valores no existen representaciones precisas, por lo que simplemente no se puede truncar un número de dígitos.

    Podría truncar la hora de imprimir usando printf cadenas de formato.

    Si usted realmente necesita para ser capaz de almacenar sólo un número limitado de dígitos, le sugerimos que utilice un fijo tipo de datos de precisión en su lugar.

    OriginalEl autor Kamil Kisiel

  3. 3

    creo que la pregunta que se debe hacer aquí es:
    ¿Por qué lo necesita trunca?

    Si su para la comparación entre los valores, tal vez usted debería considerar el uso de la prueba de epsilon. (con un extra de valor de la tolerancia, en su caso, ya que parece ser mucho mayor de lo que generalmente aceptada de epsilon).

    Si usted está a solo querer imprimirlo como 0.6000 , utilice los métodos que otros han sugerido.

    OriginalEl autor Alex Lim

  4. 1
    roundf(myfloat * powf(10, numDigits)) / powf(10, numDigits);

    Por ejemplo, en el caso de que usted está truncando tres dígitos (numDigits). Usaría:

    roundf(0.6000002 * 1000) / 1000
    //And thus:
    roundf(600.0002) / 1000
    600 / 1000
    0.6

    (Probablemente almacenar el resultado de powf en algún lugar, ya que la vas a usar dos veces).

    Debido a la forma de flotadores son normalmente almacenados en ordenadores, habría, probablemente, inexactitudes. Eso es lo que se obtiene por el uso de flotadores, aunque.

    OriginalEl autor strager

  5. 1

    Usar este:

    floor(0.6000002*10000)/10000

    OriginalEl autor JBOI

  6. 1

    Para C++11 puede utilizar std::round definido en el encabezado de <cmath>:

    auto trunc_value = std::round(value_to_trunc * 10000) / 10000;

    OriginalEl autor chema989

  7. 0

    Aquí es una función mediante el asesoramiento en otras respuestas y un ejemplo de su uso:

    #include <iostream>
    #include <cmath>
    
    static void Truncate(double& d, unsigned int numberOfDecimalsToKeep);
    
    int main(int, char*[])
    {
    
      double a = 1.23456789;
      unsigned int numDigits = 3;
    
      std::cout << a << std::endl;
    
      Truncate(a,3);
    
      std::cout << a << std::endl;
    
      return 0;
    }
    
    void Truncate(double& d, unsigned int numberOfDecimalsToKeep)
    {
        d = roundf(d * powf(10, numberOfDecimalsToKeep)) / powf(10, numberOfDecimalsToKeep);
    }

    OriginalEl autor David Doria

  8. 0

    Similar a la de otras respuestas, PERO no debe olvidar que ronda, piso y trunc son diferentes por definición. Véase la definición y ejemplo de salida de los siguientes:

    http://www.cplusplus.com/reference/cmath/trunc/

    En este caso necesitamos trucate con una precisión de 4 decimales y deshacerse de los no significativos de decimales:

    trunc(valueToTrunc*10000)/10000

    o

    value = (double)((int)(valueToTrunc*10000))/(double)10000

    OriginalEl autor Rubarb

Dejar respuesta

Please enter your comment!
Please enter your name here