Risultato non intuitivo dell'assegnazione di un numero a doppia precisione ad una variabile int in C

Risultato non intuitivo dell'assegnazione di un numero a doppia precisione ad una variabile int in C


Qualcuno potrebbe darmi una spiegazione del motivo per cui ottengo due diversi
numeri, risp. 14 e 15, come output dal codice seguente?


#include <stdio.h>  
int main()
{
double Vmax = 2.9;
double Vmin = 1.4;
double step = 0.1;
double a =(Vmax-Vmin)/step;
int b = (Vmax-Vmin)/step;
int c = a;
printf("%d %d",b,c); // 14 15, why?
return 0;
}

Mi aspetto di ottenere 15 in entrambi i casi, ma sembra che mi manchino alcuni fondamenti della lingua.


Non sono sicuro che sia rilevante, ma stavo facendo il test in CodeBlocks. Tuttavia, se digito le stesse righe di codice in qualche compilatore in linea (questo per esempio) ottengo una risposta di 15 per le due variabili stampate.


Risposte:



A parte i soliti problemi di virgola mobile, i percorsi di calcolo fino a b e c sono arrivati ​​in diversi modi. c viene calcolato salvando prima il valore come double a .


double a =(Vmax-Vmin)/step;
int b = (Vmax-Vmin)/step;
int c = a;


C consente di calcolare la matematica a virgola mobile intermedia utilizzando tipi più ampi. Controlla il valore di FLT_EVAL_METHOD da <float.h> .



OP segnalato 2


Salvando il quoziente in double a = (Vmax-Vmin)/step; , la precisione è forzata a double mentre int b = (Vmax-Vmin)/step; potrebbe essere calcolato come long double .


Questa sottile differenza deriva da (Vmax-Vmin)/step (calcolato forse come long double ) salvato come double rispetto a rimanere un long double . Uno come 15 (o appena sopra) e l'altro poco meno di 15. int il troncamento amplifica questa differenza a 15 e 14.


Su un altro compilatore, i risultati potrebbero essere stati entrambi gli stessi a causa di FLT_EVAL_METHOD < 2 o altre caratteristiche in virgola mobile.



Conversione in int da un numero a virgola mobile è grave con numeri vicini a un numero intero. Spesso meglio round() o lround() . La soluzione migliore dipende dalla situazione.