elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Optimizando función manual de modulo o resto.
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Optimizando función manual de modulo o resto.  (Leído 1,378 veces)
AlbertoBSD
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.696


🏴 Libertad!!!!!


Ver Perfil WWW
Optimizando función manual de modulo o resto.
« en: 1 Mayo 2016, 23:14 pm »

En su momento mas de alguno uso el operador modulo

r = a % n;

donde r es el resto de la división a/n donde n != 0

Ahora como estoy trabajando con numeros muy grandes de longitud variable el operador modulo como tal no me sirve, necesito crear la funcion que haga el modulo manualmente.

Si alguno de ustedes se perdio los temas, estos son algunos de ellos

Números de longitud variable en C (Numeros muy grandes)
Restas manuales en "Binario"

Ahora si hacemos la funcion modulo en forma de restas, tenemos solo le tenemos que restar al numero a el valor de n hastra que a sea menor que n

El siguiente codigo es muestra de ello de forma manual y sin ninguna optimizacion.

Código
  1. #include<stdio.h>
  2.  
  3. int main() {
  4. int resto,a,n,contador;
  5. a = 9999998;
  6. n = 3;
  7. resto = a;
  8. contador = 0;
  9. while(resto >= n) {
  10. resto-= n;
  11. contador++;
  12. }
  13. printf("resto: %u\nVeces en el ciclo %u\n",resto,contador);
  14. }

Salida:

Código:
resto: 2
Veces en el ciclo 3333332

Como vemos el numero de veces que entra al ciclo es el resultado de la división obtenido de forma iterativa mediante restas sucesivas.

Pero como se trata solo de la función "Modulo" o "Resto" no nos interesa el resultado de la división, para fines prácticos y rápidos realice esa función un poco mas optimizada y se podría optimizar mas, pero ya lo dejo a su consideración.

Código
  1. #include<stdio.h>
  2.  
  3. int main() {
  4. int resto,a,n,contador,n_pivote,resto_pivote,entrar;
  5. a = 9999998;
  6. n = 3;
  7. resto = a;
  8. contador = 0;
  9. resto_pivote = resto;
  10. n_pivote = n;
  11. entrar = 1;
  12. while(entrar && resto >= n) {
  13. resto_pivote-=n_pivote;
  14. if(resto_pivote>=0) {
  15. resto = resto_pivote;
  16. n_pivote*=2;
  17. }
  18. else {
  19. if(n_pivote > n) {
  20. n_pivote/=2;
  21. resto_pivote = resto;
  22. }
  23. else {
  24. entrar = 0;
  25. }
  26. }
  27. contador++;
  28. }
  29. printf("resto: %u\nVeces en el ciclo %u\n",resto,contador);
  30. }

Salida:

Código:
resto: 2
Veces en el ciclo 65

Como vemos el numero de veces que entra es muchísimo menor incluso si optimizamos mas la función para este ejemplo podremos llegar hasta solo 55 o 58 veces entrando al ciclo dado.

El programa utilizada una aproximación binaria ya que en cada iteracion al numero a se le resta un valor igual a n*2 veces la cantidad del ciclo anterior.

Dado que estoy trabajando con numero descomunalmente grandes... cualquier optimizan en estas funciones es mas que bien recibida.

Saludos!



Optimize aun mas el Código y ahora solo se ejecuta 42 veces para el ejemplo dado.

Ahora en lugar de incrementar el sustraendo dentro del ciclo principal lo incremento al máximo en un ciclo aparte antes del principal y posteriormente dentro del ciclo principal lo decremento hasta que sea el un multiplo de n inmediamtamente menor al valor actual de r

Código
  1. #include<stdio.h>
  2.  
  3. int main() {
  4. int resto,a,n,contador,n_pivote,entrar;
  5. a = 9999998;
  6. n = 3;
  7. resto = a;
  8. contador = 0;
  9. n_pivote = n;
  10. entrar = 1;
  11. while(n_pivote<resto) {
  12. n_pivote+=n_pivote;
  13. contador++;
  14. }
  15. while(entrar && resto >= n) {
  16. while(n_pivote>resto && n_pivote>n) {
  17. n_pivote/=2;
  18. contador++;
  19. }
  20. resto-=n_pivote;
  21. }
  22. printf("resto: %u\nVeces en el ciclo %u\n",resto,contador);
  23. }

Salida:

Código:
resto: 2
Veces en el ciclo 42

Considero yo que es el mas optimizado pero no se tal vez se puede ahorrar alguno que otro ciclo, la variable contador solo es para fines didácticos.

Saludos


« Última modificación: 7 Mayo 2016, 20:27 pm por AlbertoBSD » En línea

HardForo

Desconectado Desconectado

Mensajes: 219


HardForo.com


Ver Perfil WWW
Re: Optimizando función manual de modulo o resto.
« Respuesta #1 en: 4 Mayo 2016, 20:00 pm »

Buen trabajo! ese tipo de cosas (complejidad de los algortimos) son de las mas importantes y pocos programadores le dan la importancia que se merecen  ;-)












« Última modificación: 4 Mayo 2016, 20:29 pm por boctulus » En línea

HardForo:  foro de Hardware y programación

Se buscan Mods y colaboradores *
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
3Ds Max Orden de recursos; Optimizando...
Diseño Gráfico
MCara 3 2,243 Último mensaje 22 Junio 2005, 10:33 am
por MCara
Manual de modulo LWP en perl.
Scripting
PHAMTOM 2 2,914 Último mensaje 19 Abril 2010, 20:27 pm
por xassiz_
[Ayuda] Se Puede Saber desde que Form Se Llamó a la Función De un Modulo?
Programación Visual Basic
agus0 6 4,703 Último mensaje 8 Diciembre 2010, 12:35 pm
por Hans el Topo
[Ayuda]Como puedo llamar una variable de modulo en una funcion
Scripting
Proxmond 1 2,502 Último mensaje 22 Junio 2014, 18:27 pm
por Once
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines