redondear - Truncar un valor decimal en C++
truncar decimales c++ (9)
Creo que la pregunta que debe hacerse aquí es: ¿por qué la necesita truncada?
Si es para comparar valores, quizás debería considerar usar la prueba épsilon. (con un valor de tolerancia extra, en su caso, ya que parece ser mucho más grande que el épsilon generalmente aceptado).
Si solo desea imprimirlo como 0.6000, use los métodos que otros sugirieron.
¿Cuál es la forma más fácil de truncar una variable float
C ++ que tiene un valor de 0.6000002 a un valor de 0.6000 y almacenarla en la variable?
En primer lugar, es importante saber que los números de coma flotante son aproximados. Vea el enlace proporcionado por @Greg Hewgill para entender por qué este problema no se puede resolver por completo.
Pero aquí hay un par de soluciones para el problema que probablemente satisfaga su necesidad:
Probablemente el mejor método pero menos eficiente:
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 forma 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);
Siendo realistas, eso no es posible. No es una limitación de C ++, sino simplemente la forma en que funciona el punto flotante. Para muchos valores no hay representaciones precisas, por lo que no puede simplemente truncar a una cantidad de dígitos.
Podría truncar cuando imprima usando cadenas de formato de impresión.
Si realmente necesita almacenar solo un número limitado de dígitos, le sugiero que use un tipo de datos de precisión fija.
Una buena referencia de por qué ocurre esto puede encontrarse en Lo que todo científico informático debería saber sobre la aritmética de punto flotante por David Goldberg.
roundf(myfloat * powf(10, numDigits)) / powf(10, numDigits);
Por ejemplo, en su caso está truncando tres dígitos (numDigits). Utilizarías:
roundf(0.6000002 * 1000) / 1000
// And thus:
roundf(600.0002) / 1000
600 / 1000
0.6
(Probablemente almacenarías el resultado del powf en alguna parte, ya que lo estás usando dos veces).
Debido a cómo normalmente se almacenan los flotadores en las computadoras, probablemente haya imprecisiones. Sin embargo, eso es lo que obtienes por usar flotadores.
Utilizar esta:
floor(0.6000002*10000)/10000
Aquí hay una función que usa el consejo 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);
}
Similar a otras respuestas, PERO no debes olvidar que round, floor y trunc son diferentes por definición. Vea la definición y el ejemplo de salida de lo siguiente:
http://www.cplusplus.com/reference/cmath/trunc/
En este caso, tenemos que trucar con una precisión de 4 decimales y deshacernos de decimales no significativos:
trunc(valueToTrunc*10000)/10000
o
value = (double)((int)(valueToTrunc*10000))/(double)10000
Para C ++ 11 puede usar std::round
definido en el encabezado <cmath>
:
auto trunc_value = std::round(value_to_trunc * 10000) / 10000;