2011-01-05 69 views
6

¿Cómo puedo hacer matemáticas con cifras significativas en C++? Quiero que esto funcione correctamente con datos medidos de experimentos de química y física. Un ejemplo: 65/5 = 10. Necesitaría deshacerme de las posiciones decimales innecesarias y reemplazar algunos dígitos por 0.C++ cifras significativas

Gracias!

+7

5., 5,0, 5,00000000 son los mismos en la representación de la computadora. ¿Estás hablando de cómo * mostrar * el resultado con 2 cifras significativas? – kennytm

+0

Sí, lo soy.Editaré mi publicación para decir eso. – joshim5

+1

Supongo que quiere decir en circunstancias donde su 3.5 * 1.00 * pi lo quiere calcular usando 3.5 * 1.0 * 3.1 (a menos que esté confundido) –

Respuesta

-1

Bueno, hay good math libraries in math.h

almacenar también sus cifras en balsas, dobles o dobles largos permitirá operaciones más precisas.

Los flotadores ofrecen 7 dígitos significativos, mientras que los dobles ofrecen 16 dígitos significativos.

source

también al imprimir a cabo por lo general la gente usa _snprintf o printf y se puede formatear esos dobles, flota a la precisión con que se desea:

flotador de precisión

printf ("Valor % 8.2f ", floatVariable);

Este dice que necesita una campo total de 8 caracteres, dentro de los 8 caracteres el último 2 llevará a cabo la parte decimal .

_snprintf (buffer, sizeof (buffer), "Valor% .2f", floatVariable);

El ejemplo anterior solicita el ancho de campo mínimo y los dos últimos caracteres son para contener la parte decimal.

+5

Esos son "dígitos después del punto decimal", no [cifras significativas] (https://en.wikipedia.org/wiki/Significant_figures). Para los científicos e ingenieros hay una diferencia muy importante entre los dos. – bdesham

6

Esto debe conseguir lo que necesita:

std::cout.precision(x); // x would be the number of significant figures to output 
+0

debería escribir: cout.precision (2) < <5.34343; si quisiera mostrar 5.3? – joshim5

+0

Correcto - aquí hay documentación sobre él: http://www.cplusplus.com/reference/iostream/ios_base/precision/ –

1

Es difícil porque las cifras significativas son un concepto decimal, y las computadoras parecen ser binario. Puedes usar clases de números decimales (no sé de ninguno), o usar boost::interval, que es lo más cercano a lo que ciertamente deseas lograr.

+0

+1 para sugerir la aritmética de intervalos, aunque puede ser exagerado aquí, todavía es algo que vale la pena saber :) –

4

Puede que esta no sea la forma más eficiente, pero puede crear un tipo de datos sig fig personalizados.

class SigFigFloat 
{ 
    SigFigFloat(vector<short> digits, int decimalIndex, bool negative); 
    SigFigFloat operator+(const SigFigFloat &value); 
    SigFigFloat operator-(const SigFigFloat &value); 
    //etc... 


} 

Puede ser un montón de trabajo, pero si la aplicación de este derecho, puede ser una forma muy flexible para representar y hacer cálculos con los higos de los sig.

+0

Si estuviera haciendo esto, no haría un seguimiento solo de las cifras significativas, rastrearía el rango de error, no solo el número de cifras significativas. Eso me permitiría trabajar con cifras como 123 ± 0.2 o 123 ± 0.7, mientras que las cifras significativas solo permiten cifras como 123 ± 0.5. – Steve

1

Eso depende de cómo se muestren. Si está utilizando la familia printf, establezca la precisión (sprintf(buffer, "%.2f", myfloat)). Si está utilizando ostreams, llame a la función de precisión para establecer el número de decimales. Si está buscando el método más científico de sig higos, tendrá que escribir una función personalizada que determine la precisión en función del valor actual del flotador.

0

aquí es una solución rápida C++ 11 que trabajó para mí:

int sig_figs = 3; 
double number = 1562.654478; 

std::cout << "original number:" << number << std::endl; 

number = ([number](int number_of_sig_figs)->double{ 
    std::stringstream lStream; 
    lStream << std::setprecision(number_of_sig_figs) << number; 
    return std::stod(lStream.str()); 
})(sig_figs); 

std::cout << "rounded number:" << number << std::endl; 
Cuestiones relacionadas