[C con Clase] Hijo, comprueba tu división con esto.

marcelinux marcelinator en gmail.com
Jue Sep 25 16:49:53 CEST 2014


Hola amigos.
Espero que no se moleste nadie por tratarle de amigo sin conocernos tanto, pero, para mí, una persona que comparte su conocimiento y sus dudas, me merece el trato de amigo.
Al tema.
Soy programador de otros lenguajes y estoy empezando con c y c++.
He encontrado un programa en c que resuelve una división entera mostrando el cociente y el resto.
Lo voy a usar para comprobar las divisiones de mi hijo en el cole.
Pero, yendo más allá, lo he "convertido" en c++, mostrando cada iteración.
Ya sabes, tomo la primera cifra, divido, calculo el resto, bajo la cifra siguiente, etc.
La visualización es algo pobre porque, habiendo librerías gráficas y semigráficas (wxWidgets o nCurses), iré mejorando su aspecto.
Os pego ambos programas.
PD: Los he realizado en fuentes completos (sin cabeceras) para poder consultarlos con AvPag y RePag.
Se admite cualquier comentario constructivo

division_con_resto.c
[code]#include <stdio.h>
main(){
	int numerador=1,denominador;
	while(numerador){
		printf("Dame el numerador (0=fin)\n");
		scanf("%d",&numerador);
		if(numerador){
			printf("\nDame el denominador\n");
			scanf("%d",&denominador);
			int vueltas=0;
			while(numerador>=denominador){
				numerador=numerador-denominador;
				vueltas++;
			}
			printf("Cociente: %d\n",vueltas);
			printf("Resto: %d\n", numerador);
		}
	}
}[/code]


dividete.cpp
[code]/* Proyecto: dividete. Comprobar una división en modo texto.
 * Autor   : Marcelino Gisbert
 * Objetivo: El alumno introducirá el dividendo y el divisor.
 *           La aplicación calculará el número de cifras del dividendo y las del denominador.
 *           Se repetirán tantas divisiones enteras con las cifras del denominador
 *           para ir construyendo la división tal y como se haría a mano.
 * Ejemplo:
 *           Dado el dividendo: 35437
 *           Y el divisor.....: 283
 *           El proceso sería :
 *           Obtener el número de cifras de 35437: 5
 *           Se baja una cifra hasta que se pueda dividir.
 *           Primero el 3
 *           Se divide y se obtiene el resto de la división entera: 3
 *           Se baja la cifra siguiente: el 5.
 *           Se añade al resto anterior: 35.
 *           Se divide y se obtiene el resto: 35.
 *           Se baja la cifra siguiente: el 4.
 *           Se añade al resto anterior: 354.
 *           Se divide y se obtiene cociente (1) y el resto (71).
 *           Se baja la cifra siguiente: el 3.
 *           Se añade al resto anterior: 713.
 *           Se divide y se obtiene el cociente (2) y el resto (147).
 *           Se baja la cifra siguiente: el 7.
 *           Se añade al resto anterior: 1477.
 *           Se divide y se obtiene el cociente (5) y el resto (62).
 *           Acabaron las cifras del dividendo.
 *           El resultado se ve escalonado: cociente 125, resto 62.
 */

#include <cstdlib>
#include <string>
#include <iostream>
#include <iomanip>
#include <sstream>

//#define vervose

int cifrasNumerador;
char linea[21] = "                    ";
const char rayas[11] = "__________";
int posicionResto = 1, posicionCociente = 4;

using namespace std;

void MuestraAyuda(){
	cout << "\n\nRaúl, comprueba tu división." << endl;
	cout << "Lo ha hecho papá para que ganes tiempo en tus deberes." << endl;
	cout << "No para que hagas trampa ;)" << endl;
	cout << "Funciona así:" << endl;
	cout << "Primero te pediré el dividendo." << endl;
	cout << "\tDebes escribir un número mayor o igual a 0." << endl;
	cout << "\tSi escribes un cero, se termina." << endl;
	cout << "Después te pediré el divisor." << endl;
	cout << "Entonces iré escribiendo la división como lo harías tú en papel." << endl;
	cout << "Bueno, más o menos :)" << endl;
	cout << "Vale. ¡Vamos allá!" << endl;
}

long GetDividendo(){
	long numerador = 0;
	cout << "Dame el dividendo (Recuerda que 0 es para terminar)" << endl;
	cin >> numerador;
	return(numerador);
}

long GetDivisor(){
	long denominador = 0;
	cout << "Dame el divisor (no puede ser 0)" << endl;
	cin >> denominador;
	return(denominador);
}

string NumToString(long numero){
	stringstream flujo;
	flujo << numero;
	string cifras = flujo.str();
	#ifdef vervose
		cout << "\nGetDividendoChar\tRecibe " << numero << "\tDevuelve " << cifras << endl;
	#endif
	return(cifras);
}

int GetNumeroDeCifras(long numero){
	#ifdef vervose
		cout << "\nGetNumeroDeCifras\tRecibe " << numero ;
	#endif
	stringstream flujo;
	flujo << numero;
	string numeroChar = flujo.str();
	int cifras = numeroChar.length();
	#ifdef vervose
		cout << "\tDevuelve " << cifras << endl;
	#endif
	return(cifras);
}

void DibujaLaDivision(long dividendo, long divisor){
	cout << "\n" << dividendo;
	const int n = cifrasNumerador;
	cout << "  | " << divisor << endl;
	cout.write(linea, n);
	cout << "  L_";
	const int d = GetNumeroDeCifras(divisor) + 1;
	cout.write(rayas, d);
	cout << endl; 
}

long GetCociente(long dividendo, long divisor){
	long cociente = dividendo / divisor;
	#ifdef vervose
		cout << "\nGetCociente\tRecibe dividendo:" << dividendo << " y divisor:" << divisor << "\tDevuelve " << cociente << endl;
	#endif
	return(cociente);
}

long GetResto(long dividendo, long divisor){
	long resto = dividendo % divisor;
	#ifdef vervose
		cout << "\nGetResto\tRecibe dividendo:" << dividendo << " y divisor:" << divisor << "\tDevuelve " << resto << endl;
	#endif
	return(resto);
}

string BajaLaCifraSiguiente(string dividendoStr, string restoStr, int cifra){
	#ifdef vervose
		cout << "BajaLaCifraSiguiente\tRecibe dividendoChar:" << dividendoStr << ", resto:" << restoStr << " y cifra:" << cifra << endl;
	#endif
	char digito;
	digito = dividendoStr[cifra];
	#ifdef vervose
		cout << "Dígito " << digito << " en la cifra " << cifra << endl;
	#endif
	int posicion;
	posicion = restoStr.length();
	#ifdef vervose
		cout << "Posición donde se inserta en el resto: " << posicion << endl;
	#endif
	char *dividendoParcial = new char[posicion+1];
	int i;
	for(i = 0; i <= posicion; i++){
		#ifdef vervose
			cout << "i = " << i;
			cout << "\trestoStr[" << i << "] = " << restoStr[i] << endl;
		#endif
		dividendoParcial[i] = restoStr[i];
		#ifdef vervose
			cout << "dividendoParcial[" << i << "] = " << dividendoParcial[i] << endl;
		#endif
	}
	dividendoParcial[posicion] = digito;
	
	#ifdef vervose
		cout << "BajaLaCifraSiguiente\tDevuelve " << dividendoParcial << endl;
	#endif
	return(dividendoParcial);
}

long int Divide(long dividendo, long divisor){
	#ifdef vervose
		cout << "Divide\tRecibe dividendo:" << dividendo << " y divisor:" << divisor << endl;
	#endif
	long res = dividendo;
	if(dividendo > divisor){
		long coc = GetCociente(dividendo, divisor);
		res = GetResto(dividendo, divisor);

		posicionCociente++;
		cout << "\n" << dividendo;// << "    ";
		cout.write(linea, posicionCociente);
		cout << coc << endl;
		cout << res << endl;
	}
	#ifdef vervose
		cout << "Divide\tDevuelve resto:" << res << endl;
	#endif
	return(res);
}

int main(){
	MuestraAyuda();
	long numerador = 1, denominador = 1;
	while( numerador = GetDividendo() ){
		int r;
		if(numerador){
			if( denominador = GetDivisor() ){
				cifrasNumerador = GetNumeroDeCifras(numerador);
				DibujaLaDivision(numerador, denominador);

				string dividendoStr = NumToString(numerador);

				string restoStr;
				string numeradorParcialStr;
				numeradorParcialStr = dividendoStr[0];
				long restoParcial = strtol(numeradorParcialStr.c_str(), NULL, 0);
				int cifra;
				for(cifra = 1; cifra < cifrasNumerador; cifra++){
					restoStr = NumToString(restoParcial);
					numeradorParcialStr = BajaLaCifraSiguiente(dividendoStr, restoStr, cifra);
					long numeradorParcialLong = strtol(numeradorParcialStr.c_str(), NULL, 0);
					restoParcial = Divide(numeradorParcialLong, denominador);
					r = GetNumeroDeCifras(restoParcial);
				}
			}
		}
		const int n = r;
		cout << "\\";
		cout.write(rayas, n);
		cout << "/";
		cout << endl ;
	}
	return(0);
}[/code]

Programador y ávido de conocimiento.
Gracias a todos los que comparten.


Más información sobre la lista de distribución Cconclase