[C] Dubbio su long int (principiante)

di Anonimizzato21317 il
3 risposte
Per esercizio ho scritto un programma che converte decimali in binari.
Nonostante abbia usato tutte variabili di tipo long ho visto che il massimo numero convertibile é 2.147.483.647 .
Come mai? Una variabile long non dovrebbe poter contenere valori superiori rispetto a una variabile int?
  /*      Convertitore decimali - binari          */

#include <stdio.h>

long vettore[300];
long decimale;
long contatore;
long k;

long dectobin(long decimale) {                  /* funzione che attua la conversione */
        long resto, contatore;
        contatore = 0;
        while(decimale != 0) {
                resto = decimale % 2;           /* divide ogni cifra del decimale per due registrando il resto in una variabile  */
                decimale = decimale / 2;
                vettore[contatore] = resto;     /* registra il resto in un vettore che conterrá tutte le cifre del numero binario */
                contatore++;
                }
        return contatore;                       /* la funzione restituisce il numero di variabili (cifre contenute nel vettore  */
        }

int main() {
        printf("\n\tDigita un decimale\n");
        scanf("%ld", &decimale);
        printf("\n\tIl numero decimale %ld in binario é ", decimale);
        for (k=dectobin(decimale) - 1; k>=0; k--) {     /* k contiene il numero di variabili (cifre) inserite nel vettore  */
                printf("%ld", vettore[k]);      /* stampa le cifre contenute nel vettore, a partire dall'ultima inserita  */
                }
        printf("\n\n");
        return 0;
}   

3 Risposte

  • ...proporrei un " unsigned long int ".

    (vedi anche: /usr/include/limits.h )
  • Suggerisco anche di esplorare sperimentalmente le differenze tra long, int e short... sicuramente foriere di numerose sorprese per il neofita (e non solo).
    
    /************************************************************************/
    /** Visualizza i limiti di campo per i tipi numerici di default.       **/
    /** Include la gestione dei tipi a 64 bit.                             **/
    /** Adatto ai seguenti compilatori:                                    **/
    /** - Intel C/C++                                                      **/
    /** - Borland C/C++                                                    **/
    /** - Microsoft Visual C/C++                                           **/
    /** - Digital Mars                                                     **/
    /** - Open Watcom                                                      **/
    /** - GCC e derivati                                                   **/
    /************************************************************************/
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include "int64bit.h"
    
    #define BUFF_SIZE 64
    
    #define H_SEP_STAR "************************************************************"
    #define H_SEP_LINE "------------------------------------------------------------"
    
    /*
    ** Inserisce i separatori di migliaia (europei) in una stringa numerica.
    */
    char *numfmt(const char *in, char *out)
    {
        int p = 0;
        int size = strlen(in) * 4 / 3;
    
        memset(out, ' ', size);
        out += size +1;
        *out-- = '\0';
        in += strlen(in) -1;
    
        do
        {
            if ((p > 0) && (0 == (p % 3)))
            {
                *out-- = '.';
            }
            *out-- = *in--;
            ++p;
        } while (isdigit(*in) || ('-' == *in));
    
        return ++out;
    }
    
    /************************************************************************/
    
    int main(void)
    {
        char num_buff[BUFF_SIZE+1];
        char fmt_buff[BUFF_SIZE+1];
    
        printf("\n%s\n%s\n%s\n", H_SEP_STAR, Compiler, H_SEP_STAR);
        printf("- UNSIGNED:\n"
               "char...........: [0, %u] (%d bits per char)\n",
               UCHAR_MAX, CHAR_BIT);
    
        snprintf(num_buff, BUFF_SIZE, "%u", USHRT_MAX);
        printf("short int......: [0, %s]\n", numfmt(num_buff, fmt_buff));
    
        snprintf(num_buff, BUFF_SIZE, "%lu", UINT_MAX);
        printf("int............: [0, %s]\n", numfmt(num_buff, fmt_buff));
    
        snprintf(num_buff, BUFF_SIZE, "%lu", ULONG_MAX);
        printf("long int.......: [0, %s]\n", numfmt(num_buff, fmt_buff));
    
    /* Forma alternativa, valida per vari compilatori Windows legacy:
    #if defined(_UI64_MAX)
        _ui64toa(_UI64_MAX, num_buff, 10);
        printf("long int 64....: [0, %s]\n", numfmt(num_buff, fmt_buff));
    #endif
    */
    
    #if defined(UINT64_MAX)
        snprintf(num_buff, BUFF_SIZE, "%"PRIu64, UINT64_MAX);
        printf("long int 64....: [0, %s]\n", numfmt(num_buff, fmt_buff));
    #endif
    
        puts(H_SEP_LINE);
        printf("- SIGNED:\n"
               "char...........: [%d, %d]\n", SCHAR_MIN, SCHAR_MAX);
    
        snprintf(num_buff, BUFF_SIZE, "%d", SHRT_MIN);
        printf("short int......: [%s", numfmt(num_buff, fmt_buff));
        snprintf(num_buff, BUFF_SIZE, "%d", SHRT_MAX);
        printf(", %s]\n", numfmt(num_buff, fmt_buff));
    
        snprintf(num_buff, BUFF_SIZE, "%d", INT_MIN);
        printf("int............: [%s", numfmt(num_buff, fmt_buff));
        snprintf(num_buff, BUFF_SIZE, "%d", INT_MAX);
        printf(", %s]\n", numfmt(num_buff, fmt_buff));
    
        snprintf(num_buff, BUFF_SIZE, "%d", LONG_MIN);
        printf("long int.......: [%s", numfmt(num_buff, fmt_buff));
        snprintf(num_buff, BUFF_SIZE, "%ld", LONG_MAX);
        printf(", %s]\n", numfmt(num_buff, fmt_buff));
    
    #if defined(INT64_MAX)
        snprintf(num_buff, BUFF_SIZE, "%"PRId64, INT64_MIN);
        printf("long int 64....: [%s,\n", numfmt(num_buff, fmt_buff));
        snprintf(num_buff, BUFF_SIZE, "%"PRId64, INT64_MAX);
        printf("                   %s]\n", numfmt(num_buff, fmt_buff));
    #endif
    
        /************************************************************************/
    
        puts(H_SEP_STAR);
        puts("- FP IEEE 754:");
        printf("float..........: [%g, %g]\n", FLT_MIN, FLT_MAX);
        printf("double.........: [%g, %g]\n", DBL_MIN, DBL_MAX);
        printf("long double....: [%Lg, %Lg]\n", LDBL_MIN, LDBL_MAX);
    
        puts(H_SEP_LINE);
        printf("FLT_EPSILON....: %g\n", FLT_EPSILON);
        printf("DBL_EPSILON....: %g\n", DBL_EPSILON);
        printf("LDBL_EPSILON...: %Lg\n", LDBL_EPSILON);
        puts(H_SEP_STAR);
    
        return 0;
    }
    /* EOF: TestLim.c */
    
    Il relativo include, da salvare nella medesima directory con il nome di "int64bit.h":
    
    #ifndef __INT64BIT_H__
    #define __INT64BIT_H__
    
    #include <limits.h>
    #include <float.h>
    
    #if defined(__BORLANDC__)
        const char Compiler[] = "** Compiled with Borland C++"
                                "                              **";
     #if __BORLANDC__ >= 1400
         #include <stdint.h>
     #elif defined(_UI64_MAX)
         /* __BORLANDC__ >= 0x400 */
         typedef unsigned __int64 uint64_t;
         #define UINT64_MAX _UI64_MAX
         #define INT64_MAX _I64_MAX
         #define INT64_MIN _I64_MIN
     #endif
     #ifndef PRIu64
         #define PRIu64 "I64u"
         #define PRId64 "I64d"
     #endif
    #endif
    
    #if defined(_MSC_VER)
        const char Compiler[] = "** Compiled with Visual C/C++"
                                "                             **";
     #if _MSC_VER > 1500
         #include <stdint.h>
     #elif defined(_UI64_MAX)
         /* _MSC_VER >= 900 */
         typedef unsigned __int64 uint64_t;
         #define UINT64_MAX _UI64_MAX
         #define INT64_MAX _I64_MAX
         #define INT64_MIN _I64_MIN
     #endif
     #ifndef PRIu64
         #define PRIu64 "I64u"
         #define PRId64 "I64d"
     #endif
    #endif
    
    #if defined(__WATCOMC__)
        const char Compiler[] = "** Compiled with Open Watcom"
                                "                              **";
        #include <inttypes.h>
    #endif
    
    #if defined(__DMC__)
        const char Compiler[] = "** Compiled with Digital Mars"
                                "                             **";
        #include <inttypes.h>
    #endif
    
    #if defined(__GNUC__)
        const char Compiler[] = "** Compiled with GCC         "
                                "                             **";
        #include <inttypes.h>
    #endif
    
    #endif /* __INT64BIT_H__ */
    /* EOF: int64bit.h */
    
  • Grazie a tutti delle risposte
Devi accedere o registrarti per scrivere nel forum
3 risposte