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

 

 


Tema destacado: Rompecabezas de Bitcoin, Medio millón USD en premios


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Números de longitud variable en C (Numeros muy grandes)
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Números de longitud variable en C (Numeros muy grandes)  (Leído 2,769 veces)
AlbertoBSD
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.705


🏴 Libertad!!!!!


Ver Perfil WWW
Números de longitud variable en C (Numeros muy grandes)
« en: 30 Abril 2016, 20:40 pm »


Y si bien deben de existir varias librerías que ya lo implementen a su manera no me quería quedar sin implementar mi propia solución.

El programa ahora solo convierte cadenas de números decimales "1234" en su representación binaria en memoria, pero no se engañen esta no es la función strtol, esta puede almacenar numeros (sin signo por el momento) de cualquier longitud siempre y cuando tengamos memoria suficiente.

Vamos a ver un ejemplo de las siguientes cadenas:
"1"
"50"
"200"
"255"
"65535"
"4294967295"
"18446744073709551615"

Código
  1. int main() {
  2. numero *n;
  3. n = valor("1"); //Ejemplo de 1 solo digito
  4. free_numero(n);
  5. n = valor("50"); //Ejemplo de 2 digitos
  6. free_numero(n);
  7. n = valor("200"); //Ejemplo de 3 digitos
  8. free_numero(n);
  9. n = valor("255"); //Maximo numero de 1 byte
  10. free_numero(n);
  11. n = valor("65535"); //Maximo numero de 2 bytes
  12. free_numero(n);
  13. n = valor("4294967295"); //Maximo numero de 4 bytes
  14. free_numero(n);
  15. n = valor("18446744073709551615"); //Maximo numero de 8 bytes
  16. free_numero(n);
  17. }

Salida (Con un poco de depuración)
Código:
procesando numero 1
1 x10^0 : numeros[0]->valor: 0x456b30 01
b->valor: 0x456bb0 01
procesando numero 50
5 x10^1 : numeros[0]->valor: 0x451480 32
0 x10^0 : numeros[1]->valor: 0x451470 00
b->valor: 0x451530 32
procesando numero 200
2 x10^2 : numeros[0]->valor: 0x451470 c8
0 x10^1 : numeros[1]->valor: 0x4514f0 00
0 x10^0 : numeros[2]->valor: 0x4514b0 00
b->valor: 0x451500 c8
procesando numero 255
2 x10^2 : numeros[0]->valor: 0x451550 c8
5 x10^1 : numeros[1]->valor: 0x451420 32
5 x10^0 : numeros[2]->valor: 0x451530 05
b->valor: 0x451420 ff
procesando numero 65535
6 x10^4 : numeros[0]->valor: 0x451410 60ea
5 x10^3 : numeros[1]->valor: 0x451510 8813
5 x10^2 : numeros[2]->valor: 0x4514a0 f401
3 x10^1 : numeros[3]->valor: 0x451530 1e
5 x10^0 : numeros[4]->valor: 0x4513e0 05
b->valor: 0x451420 ffff
procesando numero 4294967295
4 x10^9 : numeros[0]->valor: 0x4514f0 00286bee
2 x10^8 : numeros[1]->valor: 0x4514a0 00c2eb0b
9 x10^7 : numeros[2]->valor: 0x4514b0 804a5d05
4 x10^6 : numeros[3]->valor: 0x457210 00093d
9 x10^5 : numeros[4]->valor: 0x4571a0 a0bb0d
6 x10^4 : numeros[5]->valor: 0x457160 60ea
7 x10^3 : numeros[6]->valor: 0x457380 581b
2 x10^2 : numeros[7]->valor: 0x456ff0 c8
9 x10^1 : numeros[8]->valor: 0x457230 5a
5 x10^0 : numeros[9]->valor: 0x4572e0 05
b->valor: 0x457210 ffffffff
procesando numero 18446744073709551615
1 x10^19 : numeros[0]->valor: 0x457180 0000e8890423c78a
8 x10^18 : numeros[1]->valor: 0x4572e0 0000203b9db5056f
4 x10^17 : numeros[2]->valor: 0x457370 00002876e1158d05
4 x10^16 : numeros[3]->valor: 0x457390 000004bfc91b8e
6 x10^15 : numeros[4]->valor: 0x457360 0000a7dcf75015
7 x10^14 : numeros[5]->valor: 0x456ff0 00c05773a57c02
4 x10^13 : numeros[6]->valor: 0x457060 0080ca396124
4 x10^12 : numeros[7]->valor: 0x457000 00409452a303
0 x10^11 : numeros[8]->valor: 0x457080 00
7 x10^10 : numeros[9]->valor: 0x457290 003c534c10
3 x10^9 : numeros[10]->valor: 0x457330 005ed0b2
7 x10^8 : numeros[11]->valor: 0x4571a0 0027b929
0 x10^7 : numeros[12]->valor: 0x4571e0 00
9 x10^6 : numeros[13]->valor: 0x457200 405489
5 x10^5 : numeros[14]->valor: 0x4570d0 20a107
5 x10^4 : numeros[15]->valor: 0x457250 50c3
1 x10^3 : numeros[16]->valor: 0x4572a0 e803
6 x10^2 : numeros[17]->valor: 0x457240 5802
1 x10^1 : numeros[18]->valor: 0x457130 0a
5 x10^0 : numeros[19]->valor: 0x457150 05
b->valor: 0x457840 ffffffffffffffff

Ahora esos son ejemplo que las funciones estándar existentes pueden manejar correctamente

Ahora bien el siguiente numero
Código:
98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210
Código
  1. int main() {
  2. numero *n;
  3. n = valor("98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210"); //Ejemplo de un Googol???
  4. free_numero(n);
  5. }

Salida sin tanta depuración:
Código:

procesando numero 98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210
b->valor: 0x777b70 ea7ec651d7671ed5de67409bdc172dc9a9d7bbd8302306b3a2e2a0cf7730b39b359cea778e3d200b9b9fb6770c6b95b395e8ab9f1474014c01ce7a3e870aa632c1ce5b705dc9f0a328d297dc436038565411ca0e338c7db56f94881768b143402be103d352ddf1beb8d5d3f59c88bb500306744fbfea44dca84d3c2cca5a88060c7168dfa57b5f86a57dda5ad3d0957639100089ca6ac40c6fbc516e76821e8026d3fce0d3fa4b1a5c5b42f723c67c3801e5b6146b5c44a3c70c7b7f63634f14211881cf4fca1bd9f7d9b8bda6db831e0a06f25384fd4262826ba6498c9ec27623314c5d7222d86a9cdf905544e7d67a056bb74b830615b2a164ba237a3889fd302bd8e092456865c265c8202d61ff55a442dc22547e68935d270fa33825e4cd331378afe199ae4ab2acea2aca6330f4727f244b72569ba75bab5a53ce22e2472f603d57314b8b02b361931bcef98c0911032db9e418e9288359f38c1fdfbe7f6a4d2fed867f76fd66d82cd107278f5ae8ec0033a226a31d2e2415f9eb72e910bfad8c2d7c02e8d44c2689de3587e51162308a50fbb776d016ea5491929011176ec8401dbed59282af7910675df3810d704db4faca2e8b44ab92d06237e872c0deef48718f59edd1541f5366e49dcabd9a00c64ec1c99f23be503b0a559e545702185426b2d94b5d7dac547ae430ebac390487d3d80b8b7b7d7d1cd2a40688f96c286cb522671faa5f272e4dd858d3f6bcbdb10fa70bebbef59aa82c18fdfd622c4b7e215c315373e366e84e0a
el numero necesita 557 bytes


Falta optimizar las funciones, el proceso de multiplicación lo hace mediante sumas continuas, trate de liberar la memoria con forme se va usando para no olvidar ninguna variable pero se me pudo pasar alguna.

Usos que se le pueden dar al programa
Si necesitas algo especializado y almacenar números extremadamente grandes para su posterior uso esta es una buena forma de hacerlo.
Yo en lo personal trabaje con esta aplicación por que necesito una forma de almacenar números de mas de 4096 bits tengan encuenta que en el ejemplo anterior el numero mas grande fue un numero de 557 bytes que son 4456 bits.
El proceso mas tardado es convertir el numero de string a binario. Posteriormente considero que las sumas son algo eficientes cuando los números ya se encuentran en su representación binaria.

Codigo completo:

Código
  1. /*
  2. Twitter @albertobsd
  3. */
  4.  
  5. #include<stdio.h>
  6. #include<stdlib.h>
  7. #include<string.h>
  8. #include<stdarg.h>
  9.  
  10. typedef unsigned char byte;
  11.  
  12. typedef struct numero_struct {
  13. byte *valor;
  14. unsigned int bytes;
  15. }numero;
  16.  
  17. numero *valorBase10(unsigned char n,unsigned char e);
  18. numero *valor(char *n);
  19. unsigned short add(unsigned char a, unsigned char b);
  20. void debug(char*s,unsigned char *ptr,unsigned int l,...);
  21. numero *add_numero(numero *a,numero *b);
  22. numero *copiar(numero* n);
  23.  
  24. numero *add_numero(numero *a,numero *b) {
  25. numero *c;
  26. unsigned char flag_a = 1,flag_b = 1,valor_a,valor_b,acarreo;
  27. unsigned short valor_c;
  28. unsigned int i = 0,max,entrar =1;
  29. //printf("add_numero\n");
  30. //debug("a->valor",a->valor,a->bytes);
  31. //debug("b->valor",b->valor,b->bytes);
  32. c = calloc(sizeof(numero),1);
  33. max = a->bytes + b->bytes;
  34. c->valor = calloc(max,1);
  35. //printf("while\n");
  36. while(entrar) {
  37. valor_c = 0;
  38. //printf("valor de i: %u\n",i);
  39. //printf("valor de a->bytes: %u\n",a->bytes);
  40. if(i < a->bytes) {
  41. valor_a = a->valor[i];
  42. }
  43. else {
  44. flag_a = 0;
  45. valor_a = 0;
  46. }
  47. //printf("valor de b->bytes: %u\n",b->bytes);
  48. if(i < b->bytes) {
  49. valor_b = b->valor[i];
  50. }
  51. else {
  52. flag_b = 0;
  53. valor_b = 0;
  54. }
  55. if(flag_a || flag_b) {
  56. if(c->valor[i] != 0) {
  57. //printf("valor de c->valor[%i]: 0x%.2x\n",i,c->valor[i]);
  58. valor_c+=c->valor[i];
  59. c->valor[i] = 0;
  60. }
  61. //printf("valor de valor_a: 0x%.2x\n",valor_a);
  62. //printf("valor de valor_b: 0x%.2x\n",valor_b);
  63. valor_c+= add(valor_a,valor_b);
  64. //printf("valor de valor_c: 0x%.4x\n",valor_c);
  65. c->valor[i] = valor_c;
  66. acarreo = valor_c >> 8;
  67. i++;
  68. if(acarreo) {
  69. //printf("valor de acarreo: 0x%.2x\n",acarreo);
  70. c->valor[i] = acarreo;
  71. //printf("valor de c->valor[%i]: %.2x\n",i,c->valor[i]);
  72. }
  73. }
  74. else {
  75. entrar = 0;
  76. }
  77. }
  78. //printf("end while\n");
  79. if(acarreo) {
  80. c->bytes = i+1;
  81. }
  82. else {
  83. c->bytes = i;
  84. }
  85. //printf("bytes: %i\n",c->bytes);
  86. //debug("c->valor",c->valor,c->bytes);
  87. //printf("End add_numero\n");
  88. return c;
  89. }
  90.  
  91. void free_numero(numero* t) {
  92. if(t) {
  93. if(t->valor) {
  94. memset(t->valor,0,t->bytes);
  95. free(t->valor);
  96. }
  97. memset(t,0,sizeof(numero));
  98. free(t);
  99. }
  100. }
  101.  
  102. numero *copiar(numero* n) {
  103. numero *t;
  104. t= calloc(sizeof(numero),1);
  105. t->bytes = n->bytes;
  106. t->valor = calloc(t->bytes,1);
  107. memcpy(t->valor,n->valor,t->bytes);
  108. return t;
  109. }
  110.  
  111. void debug(char *s,unsigned char *ptr,unsigned int l,...) {
  112. va_list args;
  113. int i = 0;
  114. char *buffer;
  115. buffer = calloc(strlen(s)*10,sizeof(char));
  116. va_start(args, l);
  117. vsprintf(buffer,s, args);
  118. printf("%s: 0x%x ",buffer,ptr);
  119. while(ptr && i < l) {
  120. printf("%.2x",ptr[i++]);
  121. }
  122. printf("\n");
  123. va_end(args);
  124. free(buffer);
  125. }
  126.  
  127. numero *valorBase10(unsigned char n,unsigned char e) {
  128. int i,j;
  129. numero *a,*b,*t,*zero,**tofree;
  130. a = calloc(sizeof(numero),1);
  131. a->bytes = 1;
  132. a->valor = calloc(a->bytes,1);
  133. a->valor[0] = n;
  134. zero = calloc(sizeof(numero),1);
  135. zero->bytes = 1;
  136. zero->valor = calloc(zero->bytes,1);
  137. zero->valor[0] = 0;
  138. b = zero;
  139. i = 0;
  140. while(i< e) {
  141. j = 0;
  142. tofree = calloc(sizeof(numero*),10);
  143. while(j < 10) {
  144. t = add_numero(a,b);
  145. tofree[j++] = t;
  146. b = t;
  147. }
  148. free_numero(a);
  149. a = copiar(b);
  150. j = 0;
  151. while(j<10) {
  152. free_numero(tofree[j++]);
  153. }
  154. free(tofree);
  155. b = zero;
  156. i++;
  157. }
  158. free_numero(b);
  159. return a;
  160. }
  161.  
  162. numero *valor(char *n) {
  163. numero *zero,*b;
  164. numero **numeros;
  165. char *ptr;
  166. int bytes;
  167. int i,j;
  168. printf("procesando numero %s\n",n);
  169. ptr = n;
  170. bytes = strlen(n);
  171. numeros = calloc(sizeof(numero*),bytes);
  172. i = 0;
  173. while(i < bytes) {
  174. numeros[i] = valorBase10(ptr[i] - '0' , (bytes-1) - i);
  175. //debug("numeros[i]",(unsigned char*)numeros[i],sizeof(numero));
  176. //debug("%c x10^%i : numeros[%i]->valor",(unsigned char*)numeros[i]->valor,numeros[i]->bytes,ptr[i],(bytes-1) - i,i);
  177. i++;
  178. }
  179. zero = calloc(sizeof(numero),1);
  180. zero->bytes = 1;
  181. zero->valor = calloc(zero->bytes,1);
  182. zero->valor[0] = 0;
  183. b = zero;
  184. i = 0;
  185. while(i < bytes) {
  186. b = add_numero(numeros[i],b);
  187. free_numero(numeros[i]);
  188. i++;
  189. }
  190. //debug("b",(unsigned char*)b,sizeof(numero));
  191. debug("b->valor",(unsigned char*)b->valor,b->bytes);
  192. free(zero);
  193. return b;
  194. }
  195. unsigned short add(unsigned char a, unsigned char b) {
  196. return a+b;
  197. }
  198. int main() {
  199. numero *n;
  200. n = valor("1"); //Ejemplo de 1 solo digito
  201. free_numero(n);
  202. n = valor("50"); //Ejemplo de 2 digitos
  203. free_numero(n);
  204. n = valor("200"); //Ejemplo de 3 digitos
  205. free_numero(n);
  206. n = valor("255"); //Maximo numero de 1 byte
  207. free_numero(n);
  208. n = valor("65535"); //Maximo numero de 2 bytes
  209. free_numero(n);
  210. n = valor("4294967295"); //Maximo numero de 4 bytes
  211. free_numero(n);
  212. n = valor("18446744073709551615"); //Maximo numero de 8 bytes
  213. free_numero(n);
  214. n = valor("98765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210987654321098765432109876543210"); //Ejemplo de un Googol???
  215. printf("el numero necesita %i bytes\n",n->bytes);
  216. free_numero(n);
  217. }


« Última modificación: 31 Octubre 2018, 08:56 am por AlbertoBSD » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
numeros grandes
Programación Visual Basic
rextor 1 3,132 Último mensaje 4 Septiembre 2005, 01:06 am
por Slasher-K
Factorial de numeros grandes en Java
Java
SAHEKA_14 0 3,561 Último mensaje 2 Octubre 2011, 04:53 am
por SAHEKA_14
[BATCH]Suma y resta números de cualquier longitud
Scripting
Binary_Death 1 3,909 Último mensaje 24 Julio 2012, 11:22 am
por BatchianoISpyxolo
Como arreglar preoblemas de numeros grandes en C++
Programación C/C++
Andrsz 9 7,841 Último mensaje 1 Enero 2014, 01:11 am
por leosansan
Como manejar números mas grandes en Vbs
Scripting
Flamer 1 1,908 Último mensaje 18 Diciembre 2016, 19:45 pm
por tincopasan
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines