[C] Dubbio su long int (principiante)

di il
3 risposte

[C] Dubbio su long int (principiante)

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

  • Re: [C] Dubbio su long int (principiante)

    ...proporrei un " unsigned long int ".

    (vedi anche: /usr/include/limits.h )
  • Re: [C] Dubbio su long int (principiante)

    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 */
    
  • Re: [C] Dubbio su long int (principiante)

    Grazie a tutti delle risposte
Devi accedere o registrarti per scrivere nel forum
3 risposte