1

Resulta que al tratar de imprimir dicha multiplicación, no me está dando el valor exacto como lo muestra la calculadora con 11 decimales de aproximación, utilizo este simple código:

#include <iostream>
#include <math.h>
#include <iomanip> 
using namespace std;

int main() {
  float b = sqrt(13);
  cout<<setprecision(12)<<2*b<<endl;

  return 0;
}

Este sí me da el valor exacto de esa multiplicación 7.21110255093

Pero cuando utilizo un método el cual me da esa misma raíz, el resultado es diferente:

Proviene de este método:

...
//Supongase que es un método el cual calcula la distancia de un punto A a un punto B, concretamente del punto (1,2,1) al punto (5,2,7)

float Punto::getDistancia(float dx1, float dy1, float dz1){
  distancia = sqrt((eje1-dx1)*(eje1-dx1) + (eje2-dy1)*(eje2-dy1) + (eje3-dz1)*(eje3-dz1));
  //distancia = sqrt(pow(eje1-dx1, 2) + pow(eje2-dy1, 2) + pow(eje3-dz1 , 2));
  return distancia;
}
...

Dando como resultado:

7.21110248566

Existe un error desde el 6to decimal.

La verdad no entiendo por qué me está dando ese resultado, ya que el código que estoy haciendo necesita de ese valor exacto para que funcione. Muchas gracias por su ayuda <3

Elmo Lawliet
  • 165
  • 1
  • 7
  • 1
    ¿Y si en lugar de float usas `double`, o `long double`? Creo que quizás debas usar `sqrtl`, ya que `sqrt` usa sólo `double`. En este momento, con `float` pierdes precisión. – Andrew Sep 09 '20 at 05:16
  • Entonces quieres decir que es mucho mejor utilizar doble para aprovechar mejor los decimales? – Elmo Lawliet Sep 09 '20 at 05:19
  • 2
    ¿Responde esto a tu pregunta? [¿Por qué mis programas no pueden hacer cálculos aritméticos correctamente?](https://es.stackoverflow.com/questions/197/por-qu%c3%a9-mis-programas-no-pueden-hacer-c%c3%a1lculos-aritm%c3%a9ticos-correctamente) – Trauma Sep 09 '20 at 05:52
  • 1
    @Trauma, me parece que esto es simplemente un problema de precisión, ya que `float` tiene precisión de unos 7 dígitos mientras que `double` alrededor de 15. Lo que comenta tu link es un problema con ciertos números "redondos" específicos, que sucederían aún con un `long double`. – Andrew Sep 09 '20 at 13:53
  • Sí, ya me quedó claro, con el tipo de dato float se pierden los decimales hasta la 7ma cifra, mientras que con el double son exactos hasta el 15vo dígito. Muchas gracias!!! – Elmo Lawliet Sep 09 '20 at 23:14
  • 1
    Recuerda que son siempre números aproximados, nunca sabes bien a partir de qué cifra empieza el error, si la 6ª o 7ª, así que si necesitas tantos dígitos, utiliza un tipo de mayor precisión. Por eso en otros sistemas está el tipo `decimal` que se almacena de otra forma y tiene una precisión exacta hasta un decimal definido. – Andrew Sep 10 '20 at 01:22

1 Answers1

1

Deberías utilizar double para tener mejor precisión, especialmente si realizas varios cálculos intermedios.

double Punto::getDistancia(double dx1, double dy1, double dz1){
  distancia = sqrt((eje1-dx1)*(eje1-dx1) + (eje2-dy1)*(eje2-dy1) + (eje3-dz1)*(eje3-dz1));
  return distancia;
}

int main() {
  double b = sqrt(13); // sqrt espera un double
  cout<<setprecision(12)<<2*b<<endl;

  return 0;
}

https://en.cppreference.com/w/c/numeric/math/sqrt

En mi caso, los resultados con float y double son, respectivamente:

7.21110248565673828 (sólo los primeros 6 dígitos son correctos)
7.21110255092797825 (15 dígitos correctos, los últimos dos dígitos no lo son)

Valor real de la calculadora:

7.211102550927978586238442534941
Andrew
  • 346
  • 1
  • 10