2

En mi código intento sacar un número de 3 cifras XYZ aleatorio y separar estas cifras independientemente X,Y,Z pero al hacerlo dependiendo del número lo hace bien o saca unos decimales que antes no estaban y redondea, hacia arriba o abajo arruinando algunos resultados.

La parte matemática está bien, se basa en poner el número como un número con decimales y quedarme con la parte entera, restar al número entero el entero y quedarme con los decimales, luego multiplicó estos para repetir el proceso.

Algunos de los números con los que me pasó esto eran:

y=562
y=92
y=485
y=260
y=687
y=477

Os dejo aquí mi código:

#include <iostream>
#include <cstdlib>
#include <time.h>
using namespace std;

float ingot(){
    
    srand(time(NULL));
    float y = rand() % 999;    
    float a = y/100;
    int b = a;
    float c = (a-b)*10;
    int d = c;
    float e = (c-d)*10;
    
    cout<<"y ="<<" "<<y<<endl;
    cout<<"a ="<<" "<<a<<endl;
    cout<<"b ="<<" "<<b<<endl;
    cout<<"c ="<<" "<<c<<endl;
    cout<<"d ="<<" "<<d<<endl;
    cout<<"e ="<<" "<<e<<endl;

    return 0;
    };

int main(){
    ingot();
};

¿Alguien sabe como arreglar esto, el fallo o cómo puedo hacerlo bien? Gracias!

Nathan
  • 21
  • 2
  • 1
    Solo como una nota, procura darle buenos nombres a las variables. Solo con `a`, `b`, `c`, etc es confuso lo que hace cada una, y honestamente no estoy seguro de que valor es el que esperas que tenga cada variable. Lo que si te puedo recomendar es que uses módulos, es mas fácil. `numero % 10` te dará las unidades, luego puedes sacar las decenas (`((numero % 100)/10`), y para las centenas solo tienes que dividirlo dentro de 100 (Todo esto asumiendo que trabajas únicamente con enteros). – Pablochaches Nov 29 '21 at 14:12
  • "La parte matemática está bien" quizás es algo confuso. En teoría de como funcionan las matemáticas para seres humanos sí, pero a nivel computacional tu implementación tiene un limitante importante, el uso de punto flotante y la dependencia de su precisión para el objetivo de la tarea. Te recomiendo este artículo https://docs.python.org/es/3/tutorial/floatingpoint.html para entender lo que sucede en las computadoras con este tipo de dato, y puedas encarar el problema de las otras maneras que te han recomendado. No es obligatorio saberlo, pero te va a solucionar dolores de cabeza como este. – Marcelo Zárate Nov 29 '21 at 16:29
  • Ok, muchas gracias por la información, ya pude arreglar el código para que haga lo que deseo sin el problema de los decimales extraños. – Nathan Nov 30 '21 at 07:54

2 Answers2

0

Piensa lo que quieres hacer. Sabes la fórmula para descomponer el número en los dígitos que quieres, pero no lo aplicas bien según las ecuaciones que pones en tu ejemplo.

También te recomiendo no trabajar con muchas variables de paso, puedes operar con los resultados de las variables anteriores, así evitarás errores, como por ejemplo al poner:

int b = a;
float c = (a-b)*10;

¿Qué esperas obtener? Si a=b, y luego haces (a-b)*10, ¿no crees que c siempre va a ser 0?

Otro comentario más, intenta darle un nombre con significado a tus variables para que puedas entender (y los demás) el código que estás realizando.

En el siguiente código te pongo un ejemplo de lo que intentas hacer. He introducido directamente un número (no aleatorio) para que veas el funcionamiento. La parte de emplear los números aleatorios te lo dejo a ti, pero no deberías tener mayor problema.

El código es el siguiente:

#include <iostream>
#include <cstdlib>
#include <time.h>
using namespace std;

float ingot(){

    int numero_in = 152, centenas, decenas, unidades;

    centenas = numero_in / 100
    decenas = (numero_in % 100) /10;
    unidades = (numero_in %10);

    cout<<"numero de ejemplo ="<<" "<<numero_in<<endl;
    cout<<"centenas ="<<" "<<centenas<<endl;
    cout<<"decenas ="<<" "<<decenas<<endl;
    cout<<"unidades ="<<" "<<unidades<<endl;

    return 0;
    };

int main(){
    ingot();
};
Londo
  • 933
  • 1
  • 3
  • 14
  • 1
    *"Si `a=b`, y luego haces `(a-b)*10`, ¿no crees que `c` siempre va a ser `0`?"* No porque `a` es un flotante, y `b` es un entero. `b` seria el resultado de pasar `a` por la función de piso, asi que `a-b` solo seria `0` si `⌊a⌋ == a` (Que solo pasaria si `y % 100 == 0`). – Pablochaches Nov 29 '21 at 14:20
0

Estás complicando las cosas de más, si quieres extraer las cifras de un número decimal, basta con calcular el módulo (%) sobre 10.

int digitos[3]{};
int numero = rand() % 999;

for (int digito = 0; numero && digito != 3; numero /= 10, ++digito)
{
    digitos[digito] = numero % 10;
}

Seguramente no has usado el módulo porque no funciona con números en coma flotante. Pero no necesitas números en coma flotante si estás trabajando con enteros. Tampoco necesitas:

  • La cabecera <time.h>, ya que es una cabecera del lenguaje ; si realmente la necesitases usar (no es tu caso) deberías usar la versión adaptada a que es <ctime>.
  • La cabecera <cstdlib>, ya que no necesitas usar ninguna de sus utilidades.
  • Las funciones srand y rand ya que deberías usar la generación de números pseudo-aleatorios de C++ accesibles desde la cabecera <random>.
  • Variables con nombres de una sola letra, ya que las variables deben tener nombres que den información de su cometido con una sola lectura.
  • Retorno de una función que no se usa, si no vas a usar el retorno de ingot, la función debería tener void como retorno.
  • Ausencia de retorno en una función con retorno, la función main debe devolver un valor entero.
PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82