Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Cero++ en 31 Diciembre 2018, 17:14 pm



Título: Sobre el truncamiento - Consulta
Publicado por: Cero++ en 31 Diciembre 2018, 17:14 pm
Código
  1. Buenas gente, estaba haciendo un ejercicio de Racionales,
  2. y estaba trabajando con dos int, para representarlo respectivamente,
  3. mi consulta es, como podría evitar que el compilador me trunque los
  4. valores cuando los divido, para verlo con valor decimal?


Título: Re: Sobre el truncamiento - Consulta
Publicado por: MAFUS en 31 Diciembre 2018, 17:17 pm
Mete el valor en un double y castea uno de los operandos a double.


Título: Re: Sobre el truncamiento - Consulta
Publicado por: Cero++ en 31 Diciembre 2018, 22:53 pm
Mete el valor en un double y castea uno de los operandos a double.

Mira, aquí te dejo una pequeña parte del código:

Código
  1. Racional A2(1,5), B2(3,3);
  2. double aux=A2.Ver_num()/A2.Ver_dem();

Deberia castear así?

Código
  1. const_cast <double>(A2.Ver_num()) o A2.Ver_dem(), cualquiera de ellos es valido?


Título: Re: Sobre el truncamiento - Consulta
Publicado por: MAFUS en 31 Diciembre 2018, 23:01 pm
Puedo intuir qué es Racional, pero ¿Què es exactamente?


Título: Re: Sobre el truncamiento - Consulta
Publicado por: Cero++ en 1 Enero 2019, 01:02 am
Puedo intuir qué es Racional, pero ¿Què es exactamente?

No sé si es retorica, así que, acá te adjunto el código:

Código
  1. #include <iostream>
  2. #include <iomanip>
  3. using namespace std;
  4. class Racional{
  5. int num,dem;
  6. public:
  7. Racional(int _num, int _dem): num(_num), dem(_dem){
  8.  
  9. }
  10. int Ver_num(){
  11. return num;
  12. }
  13. int Ver_dem(){
  14. return dem;
  15. }
  16. Racional operator+(Racional _r){
  17. int aux=(this->num*_r.dem)+(this->dem*_r.num);
  18. int aux2=this->dem*_r.dem;
  19. Racional A(aux,aux2);
  20. return A;
  21. }
  22. Racional operator*(int _i){
  23. Racional aux(this->num*_i,this->dem);
  24. return aux;
  25. }
  26. Racional operator*(Racional _r){ //Ahora ya funcionaria
  27. Racional aux(this->num*_r.num,this->dem*_r.dem);
  28. return aux;
  29. }
  30. Racional& operator++(){
  31. num+=dem;
  32. return *this;
  33. }
  34. Racional operator++(int _i){
  35. Racional aux=*this;
  36. num+=dem;
  37. return aux;
  38. }
  39. //Ejercicio 2
  40. bool operator<(Racional _r){
  41. float aux=this->num/this->dem;
  42. float aux2=_r.num/_r.dem;
  43. if(aux<aux2){
  44. return true;
  45. }
  46. return false;
  47. }
  48. bool operator>(Racional _r){
  49. float aux=this->num/this->dem;
  50. float aux2=_r.num/_r.dem;
  51. if(aux>aux2){
  52. return true;
  53. }
  54. return false;
  55. }
  56. bool operator<=(Racional _r){
  57. float aux=this->num/this->dem;
  58. float aux2=_r.num/_r.dem;
  59. if(aux<=aux2){
  60. return true;
  61. }
  62. return false;
  63. }
  64. bool operator>=(Racional _r){
  65. float aux=this->num/this->dem;
  66. float aux2=_r.num/_r.dem;
  67. if(aux>=aux2){
  68. return true;
  69. }
  70. return false;
  71. }
  72. bool operator==(Racional _r){
  73. float aux=this->num/this->dem;
  74. float aux2=_r.num/_r.dem;
  75. if(aux==aux2){
  76. return true;
  77. }
  78. return false;
  79. }
  80. bool operator!=(Racional _r){
  81. float aux=this->num/this->dem;
  82. float aux2=_r.num/_r.dem;
  83. if(aux!=aux2){
  84. return true;
  85. }
  86. return false;
  87. }
  88. };
  89.  
  90. int main(int argc, char *argv[]) {
  91. Racional A(3,5), B(2,3), C(0,1);
  92. C=A+B;
  93. cout<<C.Ver_num()<<" "<<C.Ver_dem()<<endl<<endl;
  94. C=A*B; //Da error porque no esta sobrecargado para multiplicar por racionales...
  95. C=A+B+C;
  96. C=A*B*C;//solo para multiplicar por un entero
  97. B=C++;
  98. A=++C;
  99. cout<<A.Ver_num()<<" "<<A.Ver_dem()<<endl<<endl;
  100. cout<<B.Ver_num()<<" "<<B.Ver_dem()<<endl<<endl;
  101.  
  102. /*Ejercicio 2*/
  103. Racional A2(1,5), B2(3,3);
  104. double aux=A2.Ver_num()/const_cast<double >(A2.Ver_dem());
  105. if(A2<B2){
  106. cout<<"A2 es menor que B2"; //Cómo podría evitar que se trunque el valor?
  107. }
  108. return 0;
  109. }
  110.  
  111.  

Gracias por responder, me estaba olvidando


Título: Re: Sobre el truncamiento - Consulta
Publicado por: K-YreX en 1 Enero 2019, 10:11 am
Cuando operas dos variables de tipo <int>, el resultado resulta de tipo <int> aunque lo guardes en un <double/float>. Por ejemplo:
Código
  1. int a = 5, b = 2;
  2. double res = a / b;
  3. cout << res;
Este trozo de código te mostraría por pantalla "2". Esto es porque divides (int)5 / (int)2 entonces el resultado es (int)2. Entonces aunque luego lo guardes en un <double> es como hacer <double res = 2>.

Para evitar esto se puede cambiar el tipo al menos a uno de los operandos, una operación entre dos variables numéricas distintas devuelve el resultado con el tipo más grande de los dos operandos:
- <int> / <int> = <int>
- <double> / <int> = <double> (y al revés igual)

Para no modificar el tipo puedes hacer un casting justo antes de la operación, quedaría algo así:
Código
  1. int a = 5, b = 2;
  2. double res = (double)a / b; // o a / (double)b el resultado es el mismo
Así conviertes la variable <a> en <double> pero sólo para hacer esa operación, después de hacer la división seguirá siendo de tipo <int>.

PD: Los últimos métodos de tu clase (los de comparación) tienen el mismo problema, prueba a comparar dos racionales que uno sea menor que otro pero por menos de una unidad, por ejemplo 1/3 < 1/2, el operador < te va a decir que el primero no es menor que el segundo (porque va a comparar 0 < 0, no 0.3 < 0.5). Suerte :-X


Título: Re: Sobre el truncamiento - Consulta
Publicado por: Cero++ en 2 Enero 2019, 21:35 pm
Cuando operas dos variables de tipo <int>, el resultado resulta de tipo <int> aunque lo guardes en un <double/float>. Por ejemplo:
Código
  1. int a = 5, b = 2;
  2. double res = a / b;
  3. cout << res;
Este trozo de código te mostraría por pantalla "2". Esto es porque divides (int)5 / (int)2 entonces el resultado es (int)2. Entonces aunque luego lo guardes en un <double> es como hacer <double res = 2>.

Para evitar esto se puede cambiar el tipo al menos a uno de los operandos, una operación entre dos variables numéricas distintas devuelve el resultado con el tipo más grande de los dos operandos:
- <int> / <int> = <int>
- <double> / <int> = <double> (y al revés igual)

Para no modificar el tipo puedes hacer un casting justo antes de la operación, quedaría algo así:
Código
  1. int a = 5, b = 2;
  2. double res = (double)a / b; // o a / (double)b el resultado es el mismo
Así conviertes la variable <a> en <double> pero sólo para hacer esa operación, después de hacer la división seguirá siendo de tipo <int>.

PD: Los últimos métodos de tu clase (los de comparación) tienen el mismo problema, prueba a comparar dos racionales que uno sea menor que otro pero por menos de una unidad, por ejemplo 1/3 < 1/2, el operador < te va a decir que el primero no es menor que el segundo (porque va a comparar 0 < 0, no 0.3 < 0.5). Suerte :-X

Así que así se hace un casting, la verdad es que no sabía y mire por internet pero no apareció nada, y claro, no van a funcionar los métodos por el tema de los enteros jaja eso lo sabía.

Gracias por la ayuda  ;D