Invalid operands to binary %

di il
8 risposte

Invalid operands to binary %

Salve a tutti, ho cercato già nel forum questo argomento e malgrado uscissero dei risultati non sono riuscita a visualizzare le pagine (per qualche motivo il sito me le bloccava). Ho un problema con il seguente esercizio:

Date le seguenti operazioni, scrivere un programma che dichiari opportunamente le variabili e visualizzi i risultati delle operazioni

a=6;
b='A';
c=12331222;
d=8.14245322;
e=((c*d)^2)%10;

visualizzare a, b, c, d, e.

Ho scritto questo codice:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main()
{

int a=6;
long c=12331222;
char b='A';
double d=8.14245322, e;

printf("La variabile a vale %d\n", a);
printf("La variabile c vale %d\n", c);
printf("La variabile d vale %e\n");
printf("La variabile b vale %c\n", b);
e=(pow((c*d),2))%10;
printf("La variabile e vale %e", e);


return 0; } 
affianco alla pow mi dà l'errore invalid operands to binary % (have 'double' and 'int'). Ho letto che l'operatore % opera solo su numeri interi e che la pow restituisce valori double, ho capito che c'è un conflitto per quanto riguarda i tipi di dati ma non riesco a risolvere l'errore. Avete qualche suggerimento/indizio? Ve ne sarei grata

8 Risposte

  • Re: Invalid operands to binary %

    In math.h dovrebbe esserci una funzione dedicata al modulo tra valori in virgola mobile. Guarda un po' se questo fa al caso tuo:

    http://www.cplusplus.com/reference/cmath/fmod
  • Re: Invalid operands to binary %

    AldoBaldo ha scritto:


    In math.h dovrebbe esserci una funzione dedicata al modulo tra valori in virgola mobile. Guarda un po' se questo fa al caso tuo:

    http://www.cplusplus.com/reference/cmath/fmod
    Ho provato in questo modo utilizzando la fmod ma mi dà come risultato 0.000000. L'operazione sarebbe 100.406.398,28043484/10, quindi mi dà resto zero. E' tutto corretto? Grazie per l'aiuto
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    int main()
    {
    
    int a=6;
    long c=12331222;
    char b='A';
    double d=8.14245322, e;
    
    printf("La variabile a vale %d\n", a);
    printf("La variabile c vale %d\n", c);
    printf("La variabile d vale %.8lf\n", d);
    printf("La variabile b vale %c\n", b);
    e=fmod((pow((c*d),2)), 10); 
    printf("La variabile e vale %.8lf", e);
    
    
    return 0;
    
    }
  • Re: Invalid operands to binary %

    Probabilmente il trucco ha a che fare con la "capienza" massima delle variabili di tipo double, perché se faccio (8.14245322*12331222)^2 con la calcolatrice di Windows ottengo 10081444815649310,402984305094523, non 10081444815649310. Non sono certo di saper gestire una situazione del genere, per cui mi astengo dal formulare ipotesi su possibili soluzioni.
  • Re: Invalid operands to binary %

    Non ho ben capito quale sia il problema!
    Mettiamo un attimo da parte i numeroni...

    Data l'espressione e=(c*d)^2%10, se % è l'operatore resto, sei sicura che ^ rappresenti l'elevazione a potenza? Dico questo perché in C ^ (o XOR) è un operatore bit a bit.

    In ogni caso ipotizzando che ^ rappresenti l'elevazione a potenza, la suddetta espressione si traduce (volendo utilizzare la funzione pow) in e=pow(c*d,2)%10. A questo punto provando a compilare giustamente ricevi un errore in quanto l'operatore % si aspetta come operandi due interi, mentre la funzione pow() ritorna un double. Il problema può essere risolto ricorrendo ad un semplice casting che converta il double ritornato da pow() in un intero (a tal proposito va specificato che il casting esegue un troncamento, quindi se vuoi un arrotondamento devi sommare 0.5 prima di effettuare il casting). Inoltre l'operatore resto restituisce un intero (in questo caso essendo %10, la variabile e assumerà un valore compreso nell'intervallo [0;9]) e quindi come tipo per la variabile e basta un semplice int. Alla luce di ciò l'espressione si potrebbe scrivere come:
    int e=(int)pow(c*d,2)%10.
  • Re: Invalid operands to binary %

    Nippolo ha scritto:


    Non ho ben capito quale sia il problema!
    Mettiamo un attimo da parte i numeroni...

    Data l'espressione e=(c*d)^2%10, se % è l'operatore resto, sei sicura che ^ rappresenti l'elevazione a potenza? Dico questo perché in C ^ (o XOR) è un operatore bit a bit.

    In ogni caso ipotizzando che ^ rappresenti l'elevazione a potenza, la suddetta espressione si traduce (volendo utilizzare la funzione pow) in e=pow(c*d,2)%10. A questo punto provando a compilare giustamente ricevi un errore in quanto l'operatore % si aspetta come operandi due interi, mentre la funzione pow() ritorna un double. Il problema può essere risolto ricorrendo ad un semplice casting che converta il double ritornato da pow() in un intero (a tal proposito va specificato che il casting esegue un troncamento, quindi se vuoi un arrotondamento devi sommare 0.5 prima di effettuare il casting). Inoltre l'operatore resto restituisce un intero (in questo caso essendo %10, la variabile e assumerà un valore compreso nell'intervallo [0;9]) e quindi come tipo per la variabile e basta un semplice int. Alla luce di ciò l'espressione si potrebbe scrivere come:
    int e=(int)pow(c*d,2)%10.
    Intanto aggiungo che mi sono buttata su questo esercizio probabilmente senza avere ancora tutti gli strumenti per risolverlo (è preso da un manuale della mia università e in quanto a spiegazioni i professori hanno a stento iniziato). Il casting non l'ho sperimentato/studiato ancora ma ho provato a scrivere int e=(int)pow(c*d,2)%10 come mi hai suggerito e mi restituisce -8 come risultato (nella printf ho usato %d visto che e è un intero) e non penso sia possibile come risultato Non ho capito a cosa devo aggiungere 0.5, se al risultato dell'operazione di modulo (che però senza cast non riesco proprio ad eseguire) o a cos'altro... Se invece scrivo unsigned int e=(unsigned int)pow(c*d,2)%10; mi dà come risultato 5, che come resto è più accettabile di -8 ma ammetto che sto andando un poco alla cieca...
  • Re: Invalid operands to binary %

    Dal momento che il casting opera un troncamento, se vuoi simulare un arrotondamento basta sommare 0.5 prima di effettuare il casting.
    Per esempio
    TRONCAMENTO:
    (int)3.8 ---> 3
    (int)3.2 ---> 3
    ARROTONDAMENTO:
    (int)(3.8+0.5) ---> 4
    (int)(3.2+0.5) ---> 3

    L'espressione int e=(int)pow(c*d,2)%10 è concettualmente giusta, ma ovviamente va "aggiustata" in base alla dimensione dei valori che stiamo considerando. Il motivo per cui ti esce un numero negativo è che (int)pow(c*d,2) genera un overflow, in quanto un int non è in grado di contenere la la parte intera di quella potenza; tale problema può essere risolto utilizzando un intero a 64 bit.
    Quindi in definitiva l'espressione diventa:
    int e = (int64_t)(pow(c * d, 2) + 0.5) % 10;

    P.S.
    Per utilizzare il tipo int64_t devi includere la libreria stdint.h.
  • Re: Invalid operands to binary %

    Nippolo ha scritto:


    Dal momento che il casting opera un troncamento, se vuoi simulare un arrotondamento basta sommare 0.5 prima di effettuare il casting.
    Per esempio
    TRONCAMENTO:
    (int)3.8 ---> 3
    (int)3.2 ---> 3
    ARROTONDAMENTO:
    (int)(3.8+0.5) ---> 4
    (int)(3.2+0.5) ---> 3

    L'espressione int e=(int)pow(c*d,2)%10 è concettualmente giusta, ma ovviamente va "aggiustata" in base alla dimensione dei valori che stiamo considerando. Il motivo per cui ti esce un numero negativo è che (int)pow(c*d,2) genera un overflow, in quanto un int non è in grado di contenere la la parte intera di quella potenza; tale problema può essere risolto utilizzando un intero a 64 bit.
    Quindi in definitiva l'espressione diventa:
    int e = (int64_t)(pow(c * d, 2) + 0.5) % 10;

    P.S.
    Per utilizzare il tipo int64_t devi includere la libreria stdint.h.
    Ok, è tutto chiaro, grazie. Comunque così facendo mi esce resto 0, che penso dovrebbe essere giusto come risultato... Grazie in ogni caso, mi sei stato di grande aiuto
  • Re: Invalid operands to binary %

    Di niente!

    Per assicurarti che il risultato sia corretto basta che stampi a schermo il valore pow(c * d, 2).
Devi accedere o registrarti per scrivere nel forum
8 risposte