¿Cuál es la forma más fácil de truncar una variable C++ float
que tiene un valor de 0,6000002 a un valor de 0,6000 y almacenarla de nuevo en la variable?Truncar un valor decimal en C++
Respuesta
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 al problema que probablemente satisfacer 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 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);
Realísticamente 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.
Puede truncar al imprimir utilizando cadenas de formato de impresión.
Si realmente necesita almacenar solo un número limitado de dígitos, le sugiero que utilice un tipo de datos de precisión fija.
Una buena referencia para por qué sucede esto se puede encontrar en What Every Computer Scientist Should Know About Floating Point Arithmetic por David Goldberg.
Creo que la pregunta que debe hacerse aquí es: ¿Por qué lo necesita truncado?
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 imprimir como 0.6000, utilice los métodos que otros hayan sugerido.
roundf(myfloat * powf(10, numDigits))/powf(10, numDigits);
Por ejemplo, en su caso está truncando tres dígitos (numDigits). Tendrá que utilizar:
roundf(0.6000002 * 1000)/1000
// And thus:
roundf(600.0002)/1000
600/1000
0.6
(lo que probablemente almacenar el resultado de powf en alguna parte, ya se está usando dos veces.)
Debido a la forma en flotadores son normalmente almacenados en los ordenadores, no habría probablemente sean inexactitudes. Sin embargo, eso es lo que obtienes por usar flotadores.
Utilice esta:
floor(0.6000002*10000)/10000
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);
}
Al igual que en otras respuestas, pero no debes olvidar que ronda , floor y trunc son diferentes por definición.Véase la definición y el ejemplo de salida de los siguientes:
http://www.cplusplus.com/reference/cmath/trunc/
En este caso tenemos que trucate con una precisión de 4 decimales y deshacerse de los decimales no significativos:
trunc(valueToTrunc*10000)/10000
o
value = (double)((int)(valueToTrunc*10000))/(double)10000
para C++ 11 puede utilizar std::round
se define en la cabecera <cmath>
:
auto trunc_value = std::round(value_to_trunc * 10000)/10000;
- 1. número Truncar decimal no redondear
- 2. Truncar número de dígito de valor doble en C#
- 3. ¿Cómo declarar un valor decimal en XAML?
- 4. Cómo truncar un archivo en C?
- 5. Cómo establecer un valor constante decimal
- 6. Truncar doble sin redondeo en C
- 7. C# Casting a un decimal
- 8. C# decimal separator?
- 9. Truncar un flotador en Erlang
- 10. Analizar un valor decimal de una Cadena en Ruby
- 11. Convierta un valor de color RGB en Decimal
- 12. ¿Valor de formato en XAML con un separador decimal?
- 13. Convertir el valor porcentual a valor decimal en PHP
- 14. ¿Cómo puedo convertir el valor entero en valor decimal?
- 15. C++ gamedev: truncar float a int
- 16. C# Convertir objeto a Decimal
- 17. Tipo decimal en Qt (C++)
- 18. Truncar/redondear el número entero en JavaScript?
- 19. C# sizeof decimal?
- 20. C# Decimal datatype performance
- 21. ¿Cómo convierto un decimal a un int en C#?
- 22. Sin función Truncar en PHP - ¿Opciones?
- 23. Truncar archivo
- 24. Truncar un flotador y un doble en java
- 25. ¿Cómo se dividen para obtener un valor decimal?
- 26. Retire 0s desde el final de un valor decimal
- 27. Decimal - truncate ceros finales
- 28. ANSI-C: número máximo de caracteres imprimiendo un decimal int
- 29. Extraer valor numérico de Python decimal
- 30. Decimal.TryParse no analiza mi valor decimal
Gracias por publicar el enlace Greg, estaba pensando en ese documento exacto cuando escribí mi respuesta pero no pude recordar el título por el resto de mi vida. –