Valore maggiore di un unsigned long long int

di il
5 risposte

Valore maggiore di un unsigned long long int

Salve a tutti,

Sto provando a risolvere questo esercizio:
We need to sum big numbers and we require your help.
Write a function that returns the sum of two numbers. The input numbers are strings and the function must return a string.
Io ho scritto questo codice
#include <stdlib.h>
#include <stdio.h>

char *add(const char *a, const char *b) {
  
    unsigned long long int x,y,sum;
    char *resend;
    resend = malloc(30);
    x = strtoull(a,NULL,10);
    y = strtoull(b,NULL,10);
    sum = x + y;
    sprintf(resend, "%llu", sum);
    return resend;
}
Il codice mi va a buon fine, supera tutti i test tranne ovviamente il seguente:
For inputs:
a = 63829983432984289347293874
b = 90938498237058927340892374089
Expected: 91002328220491911630239667963
Submitted: 18446744073709551614
Essendo 18446744073709551615 il più grande numero rappresentabile per un unsigned lond long int

Ho letto di un tipo denominato __int128 che potrebbe risolvermi il problema ma non riesco a capire come usarlo in quanto mi da sempre lo stesso risultato.

Come posso rappresentare questo numero così elevato?

Grazie mille

5 Risposte

  • Re: Valore maggiore di un unsigned long long int

    Non devi operare con variabili numeriche ma lavorare con le stringhe, carattere per carattere.
  • Re: Valore maggiore di un unsigned long long int

    Okok.. quindi devo fare proprio l'addizione cifra per cifra riportandomi l'eventuale riporto.. grazie mille!!!
  • Re: Valore maggiore di un unsigned long long int

    Qualcosa del genere, fatta velocemente ...
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    char *add(const char *a, const char *b) 
    {
    	int i, j, v, cy;
    
    	int lSP = strlen(a);
    	int lSM = strlen(b);
    	const char *pSP = a;
    	const char *pSM = b;
    
    	if (lSM > lSP)
    	{
    		lSP = strlen(b);
    		lSM = strlen(a);
    		pSP = b;
    		pSM = a;
    	}
    
    	char *res = (char *)calloc(lSP + 1, sizeof(char));
    	strcpy(res, pSP);
    	
    	cy = 0;
    	j = lSP-1;
    	for (i = lSM-1; i >= 0; i--)
    	{
    		v = cy + res[j] - '0' + pSM[i] - '0';
    		cy = v / 10;
    		v %= 10;
    		res[j] = '0' + v;
    		j--;
    	}
    
    	while(j)
    	{
    		v = cy + res[j] - '0';
    		cy = v / 10;
    		v %= 10;
    		res[j] = '0' + v;
    		j--;
    	}
    
    	return res;
    }
    
    int main()
    {
    	char a[] =    "63829983432984289347293874";
    	char b[] = "90938498237058927340892374089";
    
    	printf("Somma %s\n", add(a,b));
    
        return 0;
    }
    
  • Re: Valore maggiore di un unsigned long long int

    Troppo velocemente mi sa!

    Innanzitutto la condizione del while dovrebbe essere modificata in j>=0 altrimenti:
    - se i due addendi hanno la stessa lunghezza il programma crasha in quanto all'uscita del for j assume un valore negativo;
    - se i due addendi hanno lunghezza diversa, un eventuale riporto per la prima cifra del numero più lungo non verrà considerato.

    A quel punto il programma funziona a patto che la somma abbia lo stesso numero di cifre dell'addendo maggiore, infatti il problema logico di fondo del codice è proprio questo, ossia non prevedere un ulteriore carattere nell'allocazione della stringa res.

    In ogni caso io farei qualcosa del genere:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    void inverti_stringa(char *s)
    {
        unsigned int dim_s = strlen(s);
        for(unsigned int i = 0; i < dim_s / 2; ++i)
        {
            char temp = s[i];
            s[i] = s[dim_s - i - 1];
            s[dim_s - i - 1] = temp;
        }
    }
    
    char* add(const char *a, const char *b)
    {
        unsigned int i;
        unsigned int n = 0;
        unsigned int dim_a = strlen(a);
        unsigned int dim_b = strlen(b);
    	unsigned int dim_max = dim_a > dim_b ? dim_a : dim_b;
    	char *c = (char*)malloc((dim_max + 2) * sizeof(char));
    	for(i = 0; i < dim_max; ++i)
        {
            n /= 10;
            if(i < dim_a)
            {
                n += a[dim_a - i - 1] - '0';
            }
            if(i < dim_b)
            {
                n += b[dim_b - i - 1] - '0';
            }
            c[i] = n % 10 + '0';
        }
        if(n / 10)
        {
            c[i++] = '1';
        }
        c[i] = '\0';
        inverti_stringa(c);
    	return c;
    }
    
    int main()
    {
    	char a[] = "999";
    	char b[] = "21";
    	printf("%s+%s=%s\n", a, b, add(a, b));
        return 0;
    }
  • Re: Valore maggiore di un unsigned long long int

    Certo il codice andava rivisto ... avevi detto che era fatto velocemente... ma tanto l'opposto non ha proprio risposto...

    P.S. Alla fine potevi scrivere _strrev(c);
Devi accedere o registrarti per scrivere nel forum
5 risposte