Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Nucleorion en 2 Agosto 2016, 12:25 pm



Título: Poniendo a prueba los tipos de variables en c
Publicado por: Nucleorion en 2 Agosto 2016, 12:25 pm
Hola,

Estoy haciendo un programa para comprobar el tamaño y signo admitido por las variables en c y su funcionalidad en cada version de windows y arquitectura. Todo empezo porque cuando intento usar por ejemplo double se queda calculando indefinidamente.

Este es el programa:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. void main(){
  5. char tipo_char=1, tipo_char_max=1;                                                  //          -128 a 128
  6. unsigned char tipo_unsigned_char=1, tipo_unsigned_char_max=1;                       //             0 a 256
  7. short int tipo_short_int=1, tipo_short_int_max=1;                                   //        -32768 a 32767
  8. unsigned short int tipo_unsigned_short_int=1, tipo_unsigned_short_int_max=1;        //             0 a 65 535
  9. long int tipo_long_int=1, tipo_long_int_max=1;                                      //-2 147 483 648 a 2 147 483 647
  10. unsigned long int tipo_unsigned_long_int=1, tipo_unsigned_long_int_max=1;           //             0 a 4 294 967 295
  11. int tipo_int=1, tipo_int_max=1;                                                     //-2 147 483 648 a 2 147 483 647
  12. unsigned int tipo_unsigned_int=1, tipo_unsigned_int_max=1;                          //             0 a 4 294 967 295
  13. double tipo_double=1, tipo_double_max=1;                                            //           18 446 744 073 709 551 616
  14. float tipo_float=1, tipo_float_max=1;                                               //          18 446 744 073 709 551 616
  15.  
  16. while(tipo_char>0){
  17. tipo_char_max=tipo_char+(tipo_char-1);
  18. tipo_char=tipo_char*2;
  19. //printf("La variable char admite como maximo: %i \n\n",tipo_char);
  20. }
  21. printf("La variable char admite numeros entre: %i y %i \n\n",tipo_char,tipo_char_max);
  22.  
  23. while(tipo_unsigned_char>0){
  24. tipo_unsigned_char_max=tipo_unsigned_char+(tipo_unsigned_char-1);
  25. tipo_unsigned_char=tipo_unsigned_char*2;
  26. }
  27. printf("La variable unsigned char admite numeros entre: %i y %i \n\n",tipo_unsigned_char,tipo_unsigned_char_max);
  28.  
  29. while(tipo_short_int>0){
  30. tipo_short_int_max=tipo_short_int+(tipo_short_int-1);
  31. tipo_short_int=tipo_short_int*2;
  32. }
  33. printf("La variable short int admite numeros entre: %i y %i \n\n",tipo_short_int,tipo_short_int_max);
  34.  
  35. while(tipo_unsigned_short_int>0){
  36. tipo_unsigned_short_int_max=tipo_unsigned_short_int+(tipo_unsigned_short_int-1);
  37. tipo_unsigned_short_int=tipo_unsigned_short_int*2;
  38. //printf("La variable admite como maximo: %i \n\n",tipo_unsigned_short_int);
  39. }
  40. printf("La variable unsigned short int admite numeros entre: %i y %i \n\n",tipo_unsigned_short_int,tipo_unsigned_short_int_max);
  41.  
  42. while(tipo_long_int>0){
  43. tipo_long_int_max=tipo_long_int+(tipo_long_int-1);
  44. tipo_long_int=tipo_long_int*2;
  45. //printf("La variable admite como maximo: %i \n\n",tipo_long_int);
  46. }
  47. printf("La variable long int admite numeros entre: %i y %i \n\n",tipo_long_int,tipo_long_int_max);
  48.  
  49. while(tipo_unsigned_long_int>0){
  50. tipo_unsigned_long_int_max=tipo_unsigned_long_int+(tipo_unsigned_long_int-1);
  51. tipo_unsigned_long_int=tipo_unsigned_long_int*2;
  52. //printf("La variable admite como maximo: %i \n\n",tipo_unsigned_long_int);
  53. }
  54. printf("La variable unsigned long int admite numeros entre: %u y %u \n\n",tipo_unsigned_long_int,tipo_unsigned_long_int_max);
  55.  
  56. while(tipo_int>0){
  57. tipo_int_max=tipo_int+(tipo_int-1);
  58. tipo_int=tipo_int*2;
  59. //printf("La variable admite como maximo: %i \n\n",tipo_long_int);
  60. }
  61. printf("La variable int admite numeros entre: %i y %i \n\n",tipo_int,tipo_int_max);
  62.  
  63. while(tipo_unsigned_int>0){
  64. tipo_unsigned_int_max=tipo_unsigned_int+(tipo_unsigned_int-1);
  65. tipo_unsigned_int=tipo_unsigned_int*2;
  66. //printf("La variable admite como maximo: %i \n\n",tipo_unsigned_int);
  67. }
  68. printf("La variable unsigned int admite numeros entre: %u y %u \n\n",tipo_unsigned_int,tipo_unsigned_int_max);
  69.  
  70. while(tipo_float>0){
  71. tipo_float_max=tipo_float+(tipo_float-1);
  72. tipo_float=tipo_float*2;
  73. //printf("La variable admite como maximo: %i \n\n",tipo_float);
  74. }
  75. //printf("La variable float admite numeros entre: %4.2f y %4.2f \n\n",tipo_float,tipo_float_max);
  76.  
  77. while(tipo_double>0){
  78. tipo_double_max=tipo_double+(tipo_double-1);
  79. tipo_double=tipo_double*2;
  80. //printf("La variable admite como maximo: %i \n\n",tipo_double);
  81. }
  82. //tipo_double=18446744073709551616;
  83. //printf("La variable double admite numeros entre: %4.2f y %4.2f \n\n",tipo_double,tipo_double_max);
  84.  
  85.  
  86.  
  87. system("pause");
  88.  
  89.  
  90. }
  91.  
  92.  

Y este el resultado:
Citar
La variable char admite numeros entre: -128 y 127

La variable unsigned char admite numeros entre: 0 y 255

La variable short int admite numeros entre: -32768 y 32767

La variable unsigned short int admite numeros entre: 0 y 65535

La variable long int admite numeros entre: -2147483648 y 2147483647

La variable unsigned long int admite numeros entre: 0 y 4294967295

La variable int admite numeros entre: -2147483648 y 2147483647

La variable unsigned int admite numeros entre: 0 y 4294967295

_


Y tanto el tipo double como float se queda ahi trabajando pero no termina ni en varios minutos.

El ordenador es un i5, 8GB de RAM. El SO Win7 64bits. El compilador minGW64 gcc.exe. El editor Notepad++.

Que puede fallar para que double y float no me den el resultado esperado?


Título: Re: Poniendo a prueba los tipos de variables en c
Publicado por: Nucleorion en 2 Agosto 2016, 12:31 pm
Vale ya he visto que tengo mal el formato en los printf. Voy a revisarlo


Título: Re: Poniendo a prueba los tipos de variables en c
Publicado por: AlbertoBSD en 2 Agosto 2016, 12:35 pm
No termina?

Código
  1. system("pause");


Título: Re: Poniendo a prueba los tipos de variables en c
Publicado por: Nucleorion en 2 Agosto 2016, 13:13 pm
No, no termina. Nunca sale lo de pulse una tecla para continuar.

Edito el post inicial ya que unsigned long int y unsigned int, fallaban porque ponia %i en vez de %u

En cuanto a los dos ultimos tipos double y float aunque comente el printf se quedan atascados supuestamente calculando y consumiendo el 25% del procesador cuatro nucleos.

Que hago mal para que no termine de multiplicarse por dos. double y float no se resetean como los otros tipos cuando se desbordan?


Título: Re: Poniendo a prueba los tipos de variables en c
Publicado por: ivancea96 en 2 Agosto 2016, 13:36 pm
Cuando un float, double o long double llega al límite, se establece a un valor que se trata como "infinito". Mientras que nos números enteros se manejan directamente como están en la memoria, los float tienen un formato especial.
http://en.cppreference.com/w/c/types/limits (http://en.cppreference.com/w/c/types/limits)


Título: Re: Poniendo a prueba los tipos de variables en c
Publicado por: Nucleorion en 2 Agosto 2016, 19:11 pm
infinito, que bien!! infinito es mayor que cero!! asi que no acababa nunca XD

Hay alguna manera de saber cuando se ha desbordado un double y un float? Es decir, no quiero usar una constante para ver si se llega al final. Quiero desbordar el tipo detectarlo, e imprimir su valor mayor y menor, igual que hago en los tipos mas pequeños.



Título: Re: Poniendo a prueba los tipos de variables en c
Publicado por: ivancea96 en 2 Agosto 2016, 21:32 pm
Si pones 1.0/0.0, obtedrás el valor infinito. Cuidado de no poner 1/0, ya que estos son enteros, y tu programa tendrá un error de división por cero.


Título: Re: Poniendo a prueba los tipos de variables en c
Publicado por: Nucleorion en 3 Agosto 2016, 17:36 pm
Funciona lo de dividir por cero para comparar con el infinito!!

Dejando los decimales aparte, que veo que tienen tela. me quedan unas dudas.

int, long, y long int es lo mismo? o tengo algo mal?


Título: Re: Poniendo a prueba los tipos de variables en c
Publicado por: AlbertoBSD en 4 Agosto 2016, 01:34 am
Actualmente en la mayoria de los sistemas de 32 bits tienen dicho espacio de almacenamiento, la diferencia radicaba en aequitecturas de de 16 bits donde un int tenia espacio para 16 bits y un long era el doble de esto.

http://stackoverflow.com/questions/900230/difference-between-long-and-int-data-types




Título: Re: Poniendo a prueba los tipos de variables en c
Publicado por: Nucleorion en 5 Agosto 2016, 11:47 am
Y en mi caso que el sistema es de 64 bits? realmente se puede manejar un bloque de 32 bits?

Que hace, optimizar y guardar en memoria dos de 32 juntos, o que?


Título: Re: Poniendo a prueba los tipos de variables en c
Publicado por: ivancea96 en 5 Agosto 2016, 13:18 pm
Generalmente: char 1, short 2, int 4, long long 8.

Si quieres verdadera precisión al conocer el tamaño de las variables, tienes:
Código
  1. int8_t - uint8_t
  2. int16_t - uint16_t
  3. int32_t - uint32_t
  4. int64_t - uint64_t

Más información de los tipos en: http://www.cplusplus.com/reference/cstdint/ (http://www.cplusplus.com/reference/cstdint/)

Esos están asegurados de tener ese tamaño. Son todos tipos enteros, con o sin signo (según tengan la 'u' delante)


Título: Re: Poniendo a prueba los tipos de variables en c
Publicado por: Nucleorion en 26 Septiembre 2016, 18:18 pm
Joer, no vi el cambio de pagina.

Muchas gracias. Intente usar ese tipo de declaracion pero no me funcionó. Volveré a probar.

El programa quedo asi:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <limits.h>
  4.  
  5. void main(){
  6. char tipo_char=1, tipo_char_max=1;                                                  //          -128 a 128
  7. unsigned char tipo_unsigned_char=1, tipo_unsigned_char_max=1;                       //             0 a 256
  8. short int tipo_short_int=1, tipo_short_int_max=1;                                   //        -32768 a 32767
  9. unsigned short int tipo_unsigned_short_int=1, tipo_unsigned_short_int_max=1;        //             0 a 65 535
  10. int tipo_int=1, tipo_int_max=1;                                                     //-2 147 483 648 a 2 147 483 647
  11. long tipo_long=1, tipo_long_max=1;                                                  //-2 147 483 648 a 2 147 483 647
  12. long int tipo_long_int=1, tipo_long_int_max=1;                                      //-2 147 483 648 a 2 147 483 647
  13. unsigned int tipo_unsigned_int=1, tipo_unsigned_int_max=1;                          //             0 a 4 294 967 295
  14. unsigned long tipo_unsigned_long=1, tipo_unsigned_long_max=1;                       //             0 a 4 294 967 295
  15. unsigned long int tipo_unsigned_long_int=1, tipo_unsigned_long_int_max=1;           //             0 a 4 294 967 295
  16. long long tipo_long_long=1, tipo_long_long_max=1;                            // -9223372036854775808 a  9223372036854775807
  17. unsigned long long tipo_unsigned_long_long=1, tipo_unsigned_long_long_max=1; //                    0 a 18 446 744 073 709 551 616
  18.  
  19. int bits=1;
  20.  
  21. while(tipo_char>0){
  22. tipo_char_max=tipo_char+(tipo_char-1);
  23. tipo_char=tipo_char*2;
  24. //printf("char admite como maximo: %i \n\n",tipo_char);
  25. bits++;
  26. }
  27. printf("char ................. %ibits de                    %i a                  %i \n\n",bits,tipo_char,tipo_char_max);
  28. bits=0;
  29. while(tipo_unsigned_char>0){
  30. tipo_unsigned_char_max=tipo_unsigned_char+(tipo_unsigned_char-1);
  31. tipo_unsigned_char=tipo_unsigned_char*2;
  32. bits++;
  33. }
  34. printf("unsigned char ........ %ibits .. de                    %i a                  %i \n\n",bits,tipo_unsigned_char,tipo_unsigned_char_max);
  35. bits=1;
  36. while(tipo_short_int>0){
  37. tipo_short_int_max=tipo_short_int+(tipo_short_int-1);
  38. tipo_short_int=tipo_short_int*2;
  39. bits++;
  40. }
  41. printf("short int ........... %ibits .. de               %i a                %i \n\n",bits,tipo_short_int,tipo_short_int_max);
  42. bits=0;
  43. while(tipo_unsigned_short_int>0){
  44. tipo_unsigned_short_int_max=tipo_unsigned_short_int+(tipo_unsigned_short_int-1);
  45. tipo_unsigned_short_int=tipo_unsigned_short_int*2;
  46. //printf("admite como maximo: %i \n\n",tipo_unsigned_short_int);
  47. bits++;
  48. }
  49. printf("unsigned short int .. %ibits .. de                    %i a                %i \n\n",bits,tipo_unsigned_short_int,tipo_unsigned_short_int_max);
  50. bits=1;
  51. while(tipo_int>0){
  52. tipo_int_max=tipo_int+(tipo_int-1);
  53. tipo_int=tipo_int*2;
  54. //printf("admite como maximo: %i \n\n",tipo_long_int);
  55. bits++;
  56. }
  57. printf("int ................. %ibits .. de          %i a           %i \n\n",bits,tipo_int,tipo_int_max);
  58. bits=1;
  59. while(tipo_long>0){
  60. tipo_long_max=tipo_long+(tipo_long-1);
  61. tipo_long=tipo_long*2;
  62. //printf("admite como maximo: %ld \n\n",tipo_long_int);
  63. bits++;
  64. }
  65. printf("long ................ %ibits .. de          %ld a           %ld \n\n",bits,tipo_long,tipo_long_max);
  66. bits=1;
  67. while(tipo_long_int>0){
  68. tipo_long_int_max=tipo_long_int+(tipo_long_int-1);
  69. tipo_long_int=tipo_long_int*2;
  70. //printf("admite como maximo: %i \n\n",tipo_long_int);
  71. bits++;
  72. }
  73. printf("long int ............ %ibits .. de          %i a           %i \n\n",bits,tipo_long_int,tipo_long_int_max);
  74. bits=0;
  75. while(tipo_unsigned_long_int>0){
  76. tipo_unsigned_long_int_max=tipo_unsigned_long_int+(tipo_unsigned_long_int-1);
  77. tipo_unsigned_long_int=tipo_unsigned_long_int*2;
  78. //printf("admite como maximo: %i \n\n",tipo_unsigned_long_int);
  79. bits++;
  80. }
  81. printf("unsigned long int ... %ibits .. de                    %u a           %u \n\n",bits,tipo_unsigned_long_int,tipo_unsigned_long_int_max);
  82. bits=0;
  83. while(tipo_unsigned_int>0){
  84. tipo_unsigned_int_max=tipo_unsigned_int+(tipo_unsigned_int-1);
  85. tipo_unsigned_int=tipo_unsigned_int*2;
  86. //printf("admite como maximo: %i \n\n",tipo_unsigned_int);
  87. bits++;
  88. }
  89. printf("unsigned int ........ %ibits .. de                    %u a           %u \n\n",bits,tipo_unsigned_int,tipo_unsigned_int_max);
  90. bits=0;
  91. while(tipo_unsigned_long>0){
  92. tipo_unsigned_long_max=tipo_unsigned_long+(tipo_unsigned_long-1);
  93. tipo_unsigned_long=tipo_unsigned_long*2;
  94. //printf("admite como maximo: %i \n\n",tipo_unsigned_long);
  95. bits++;
  96. }
  97. printf("unsigned long ....... %ibits .. de                    %u a           %u \n\n",bits,tipo_unsigned_long,tipo_unsigned_long_max);
  98. bits=1;
  99. while(tipo_long_long>0){
  100. tipo_long_long_max=tipo_long_long+(tipo_long_long-1);
  101. tipo_long_long=tipo_long_long*2;
  102. //printf("admite como maximo: %ll \n",tipo_long_long);
  103. bits++;
  104. }
  105. printf("long long ........... %ibits .. de %lld a  %lld \n\n",bits,tipo_long_long,tipo_long_long_max);
  106. bits=0;
  107. while(tipo_unsigned_long_long>0){
  108. tipo_unsigned_long_long_max=tipo_unsigned_long_long+(tipo_unsigned_long_long-1);
  109. tipo_unsigned_long_long=tipo_unsigned_long_long*2;
  110. //printf("admite como maximo: %llu \n",tipo_unsigned_long_long);
  111. bits++;
  112. }
  113. printf("unsigned long long .. %ibits .. de                    %llu a %llu \n\n",bits,tipo_unsigned_long_long,tipo_unsigned_long_long_max);
  114.  
  115. system("pause");
  116.  
  117.  
  118. /*
  119. %d--> for int
  120.  
  121. %ld--> for long int
  122.  
  123. %lld--> for long long int
  124.  
  125. %llu--> for unsigned long long int
  126. */
  127. }
  128.  

Y el resultado con Notepad++ y MinGW es este:

Citar
char ................. 8bits de                    -128 a                  127

unsigned char ........ 8bits .. de                    0 a                  255

short int ........... 16bits .. de               -32768 a                32767

unsigned short int .. 16bits .. de                    0 a                65535

int ................. 32bits .. de          -2147483648 a           2147483647

long ................ 32bits .. de          -2147483648 a           2147483647

long int ............ 32bits .. de          -2147483648 a           2147483647

unsigned long int ... 32bits .. de                    0 a           4294967295

unsigned int ........ 32bits .. de                    0 a           4294967295

unsigned long ....... 32bits .. de                    0 a           4294967295

long long ........... 64bits .. de -9223372036854775808 a  9223372036854775807

unsigned long long .. 64bits .. de                    0 a 18446744073709551615


Título: Re: Poniendo a prueba los tipos de variables en c
Publicado por: ivancea96 en 26 Septiembre 2016, 19:30 pm
La razón por la cual están esas variables es porque no está asegurado que esos tamaños sean así siempre.
Lo único asegurado es que los tamaños siguen estas condiciones:
Código
  1. char <= short <= int <= long <= long long