C Prüfen, ob Eingabe Double ist?

6 Antworten

Man kann es unschön machen, in dem du eine double einlesen lässt und dann eine andere int variable nimmst und auf die einmal deine double typecastest und dann schaust du dir die differenz zwischen int und double an, falls die ungleich 0 ist handelt es sich um eine double. Jetzt ist die Frage, ob dein Programm auch Zahlen wie 1.00000 als double sehen soll?


codinginc 
Beitragsersteller
 17.12.2019, 23:09

Geht leider auch nicht, da z.B. 123q beim Cast nach int zu 123 wird und der "Fehler" verloren geht

Wie soll das gehen? Auch eine "0" kannst du als Double einlesen und Speichern. Und wie in c üblich, kannst du jede Variable als beliebigen Datentyp interpretieren. In c gibt es keine Typüberwachung, Du bist als Programmierer selber dafür verantwortlich, den richtigen Typ zu nutzen. Selbst eine Stringvarable kannst due als Zahlenwert benutzen. Je nach verwendeter Maschine hat der String z.B. den Byte-Wert der ASCII Representation des ersten Zeichens. oder den word-Wert der ASCII Repräsentation der ersten beiden Zeichen bzw. vier Zeichen als double. Und wenn da nur ein einzelnes Byte steht, dann werden eben die Zeichen, die zufällig gerade dahinter stehen interpretiert. Das ist halt c, eine der archaischten Programmiersprachen die es gibt.

Du kannst die Funktion strtod verwenden. Die gibt laut manual 0 zurück wenn die eingabe nicht zu double konvertiert werden kann und nptr == endptr.

Also du kannst schreiben:

int isDouble(const char* string)
{
   char * endPtr = string;
   return !(strtod(string, &endPtr) == 0 && string == endPtr);
}

codinginc 
Beitragsersteller
 17.12.2019, 23:06

Nein, weil z.B. 123q zu 123 ausgewertet wurd und 1 zurück gibt :(

PeterKremsner  17.12.2019, 23:09
@codinginc

Ja 123 ist auch ein gültiger double ;)

Wenn du diese Zeichenkette auch nicht willst dann musst du hald prüfen ob bei erfolgreicher Konversion endPtr auf das Ende von String zeigt.

Also

int isDouble(const char* string)
{
   char * endPtr = string;
   if(strtod(string, &endPtr) == 0 && string == endPtr)
       return 0;
   else
   {
       return (endPtr - strlen(string)) == string;
   }
}
PeterKremsner  17.12.2019, 23:12
@codinginc

Hab gerade einen Code dazu geschrieben, musst aber prüfen ob der geht, der ist jetzt rein mal ohne tiefere Überlegung entstanden.

PeterKremsner  17.12.2019, 23:17
@codinginc

Du sagst dem Compiler dass der Funktionsaufrauf die Daten in dem String nicht verändert, das erlaubt dem Compiler einige Optimierungen zu machen, da er weiß dass nach dem Aufruf von isDouble, das selbe im String drinnen steht wie vorher.

Für diese Funktion sollte sogar const char * const string möglich sein, was dem Compiler zusätzlich noch sagt, dass der Pointer selbst ebenfalls nicht in der Funktion verändert wird.

codinginc 
Beitragsersteller
 17.12.2019, 23:27
@PeterKremsner

Kann ich dir vielleicht mal eine private Nachricht schreiben?

Und danke übrigens :)

Lösungsidee (noch nicht voll durchdacht, sie könnte also ergänzungsbedürftig sein):

Ich würde die Dezimaldarstellung

  • zuerst als String s1 einlesen,
  • dann als double d1 einlesen,
  • dann d1 wieder als double ausdrucken (mit einer Stellenzahl, die größer sein sollte als der auf deinem Rechner größtmögliche double-Wert)
  • dann die so ausgedruckte Dezimaldarstellung wieder als double d2 einlesen, aber auch als String s2.

Wenn dann die Werte von s1 und d1 mit denen von s2 und d2 übereinstimmen, scheint mir bewiesen, dass die ursprünglich gegebene Dezimaldarstellung einen auf deinem Rechner darstellbaren double-Wert präsentiert.

Hey,

ich habe hier gerade mal was zusammengebaut. Ich glaube ich habe keine Fälle vergessen. Aber vielleicht findest du ja noch was!

https://pastebin.com/sJBX0z9T

Das gibt dann folgendes aus:

Bild zum Beitrag

Woher ich das weiß:Studium / Ausbildung
 - (Computer, programmieren, Informatik)