Nicht intuitives Ergebnis der Zuweisung einer Zahl mit doppelter Genauigkeit zu einer int-Variablen in C

Nicht intuitives Ergebnis der Zuweisung einer Zahl mit doppelter Genauigkeit zu einer int-Variablen in C


Kann mir jemand erklären, warum ich zwei verschiedene
Nummern bekomme, bzw. 14 und 15, als Ausgabe des folgenden Codes?


#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;
}

Ich erwarte, in beiden Fällen 15 zu bekommen, aber es scheint, dass mir einige Grundlagen der Sprache fehlen.


Ich bin mir nicht sicher, ob es relevant ist, aber ich habe den Test in CodeBlocks durchgeführt. Wenn ich jedoch die gleichen Codezeilen in einen Online-Compiler (zum Beispiel diesen) eingebe, erhalte ich eine Antwort von 15 für die beiden gedruckten Variablen.


Antworten:



Abgesehen von den üblichen Fließkommaproblemen sind die Berechnungspfade zu b und c kommen auf unterschiedliche Weise an. c wird berechnet, indem zuerst der Wert als double a gespeichert wird .


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


C ermöglicht die Berechnung von Zwischen-Gleitkomma-Mathematik mit breiteren Typen. Überprüfen Sie den Wert von FLT_EVAL_METHOD ab <float.h> .



OP hat 2 gemeldet


Durch Speichern des Quotienten in double a = (Vmax-Vmin)/step; , wird die Genauigkeit auf double gezwungen wohingegen int b = (Vmax-Vmin)/step; könnte als long double berechnet werden .


Dieser feine Unterschied ergibt sich aus (Vmax-Vmin)/step (berechnet vielleicht als long double ) als double gespeichert statt ein long double zu bleiben . Einer als 15 (oder knapp darüber) und der andere knapp unter 15. int Abschneiden verstärkt diesen Unterschied auf 15 und 14.


Auf einem anderen Compiler waren die Ergebnisse aufgrund von FLT_EVAL_METHOD < 2 möglicherweise beide gleich oder andere Fließkommamerkmale.



Umstellung auf int von einer Gleitkommazahl ist bei Zahlen in der Nähe einer ganzen Zahl schwerwiegend. Oft besser zu round() oder lround() . Die beste Lösung ist situationsabhängig.