PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : c Warum geht das nicht?


Gast
2008-08-08, 15:29:17
Warum gibt mir dieser Code 1 und nicht 1.3333333 aus?


class Program
{
static void Main()
{
double zahl; //Variablen def.
double zahl1;

zahl = 4 / 3;
zahl1 = 1.33333333;

Console.WriteLine(zahl);
Console.WriteLine(zahl1);
}
}


Vielen Dank
John

Baalzamon
2008-08-08, 15:42:54
Ich schätze du meinst die Variable 'zahl' und nicht 'zahl1', richtig?

Das liegt einfach daran, das der Compiler implizit int Werte hernimmt, wenn du Zahlen ohne Dezimalstelle schreibst. Machst du aus der ganzen Geschichte ein 4.0 / 3.0 wird auch das richtige Ergebnis rauskommen.

Soweit zumindest mien rudimentäres Wissen, wenn ich Scheisse gelabert habe, wird schon jemand kommen und das zurechtrücken. ;)

Trap
2008-08-08, 15:43:26
Weil zuerst die rechte Seite zu 1 ausgewertet wird und erst danach zu 1.0 konvertiert wird.

Sephiroth
2008-08-08, 15:44:49
Weil 4 und 3 vom Typ int sind, wird auch das Ergebnis der Operation / als int ausgegeben (Nachkommastellen abgeschnitten).

http://openbook.galileocomputing.de/c_von_a_bis_z/c_008_001.htm#RxxobKap0080010400269F1F03E1A3

Gast
2008-08-08, 15:53:54
Ja jetzt klappt es.
Vielen Dank an euch allen

John

Gast
2008-08-08, 23:33:26
Weil zuerst die rechte Seite zu 1 ausgewertet wird und erst danach zu 1.0 konvertiert wird.


Genau so ist es!

Der_Donnervogel
2008-08-11, 19:20:42
Das Problem gibt es übrigens auch in anderen Sprachen (z.B. Java) und man sollte da gut aufpassen. Ich kann zwar nachvollziehen warum die Lösung so umgesetzt wurde, aber ich finde es trotzdem ziemlich krank, da es sehr fehleranfällig ist. In diesem Punkt finde ich die Lösung von VB viel besser, wo auch wirklich die Ergebnisse rauskommen die man sich intuitiv erwartet. Zur Unterhaltung hier noch ein Ratespiel. Welche Ergebnisse kommen wohl heraus?

double zahl;
double zahl1;
double zahl2;
double zahl3;
zahl = 5 / 2.0 * 1;
zahl1 = 5 / 2 * 1.0;
zahl2 = 1.0 * 5 / 2;
zahl3 = 1.0 * (5 / 2);

Lösung:
getestet mit Java:

5 / 2.0 * 1 = 2.5
5 / 2 * 1.0 = 2.0
1.0 * 5 / 2 = 2.5
1.0 * (5 / 2) = 2.0

Coda
2008-08-11, 19:29:19
Das kann man so und so sehen. In VB hast du dann das Problem wenn du wirklich mal einen Integer-Typ willst und ihn aber nicht als Literal hinschreiben kannst.

Es ist eine gute Angewohnheit eben immer FP-Literale zu verwenden (inkl. f wenn man float meint). Also 1.0f (float) oder 1.0 (double).

Der_Donnervogel
2008-08-12, 01:10:27
Wenn man wirklich einen Typ erzwingen will, kann man das auch in VB machen. Zumindest in VB.Net gibt es auch Literalzeichen mit denen man die Typen von Literalen erzwingen kann. zB 1R ist 1.0 als double. Davon abgesehen kann man auch mit Funktionen wie CInt, CLng usw. Typen, ähnlich einem cast bei anderen Sprachen, erzwingen.

Wobei ich ehrlich gesagt in solchen "Zweifelsfällen" grundsätzlich caste und klammere. Ich habe es öfters mal mit verschiedenen Sprachen (und das teilweise gleichzeitig) zu tun. Da ist es mir einfach zu gefährlich, versehentlich etwas bei den implizierten Typkonvertierungen und den Vorrangregeln zu verwechseln. So oft kommen solche Berechnungen wo verschiedene Typen direkt verrechnet werden zum Glück nicht vor (zumindest nicht in dem Code den ich bisher gemacht habe).

ThEgRaZe
2008-08-12, 01:57:15
Ist das hier eine Neuerfindung von C?

Echtes C sieht auf jeden Fall schöner und einfacher aus als dieses .NET.

Coda
2008-08-12, 02:47:33
Was ist dort "einfacher"? Die Cast-Regeln um die es gerade geht sind in C/C++ und C# (um das es hier geht) sowie Java exakt die gleichen.

Und was an

#include <stdio.h>

int main()
{
double zahl; //Variablen def.
double zahl1;

zahl = 4 / 3;
zahl1 = 1.33333333;

printf("%lf\n",zahl);
printf("%lf\n",zahl2);

return 0;
}
ansonsten schöner sein sollte erschließt sich mir auch nicht. Vor allem das printf-Zeug ist doch major ugly.

ThEgRaZe
2008-08-12, 03:09:57
Ich wollte damit nur ausdrücken, dass der Threadtitel falsch ist ;)

Und warum so kompliziert wenn es doch einfacher geht?^^
#include <stdio.h>
int main() {
double zahl, zahl1;

zahl = 4 / 3;
zahl1 = 1.33333333;

printf("%lf\n%lf\n",zahl, zahl1);
return 0;
}

Abraxus
2008-08-12, 04:59:36
Bist du stolz drauf, das du die öffnende Klammer hochgezogen hast, oder weil das printf nun noch viel unleserlicher ist? Wuhu, 2 Zeilen gespaart, dafür muss ich nun 2min länger auf den Code schauen, um ihn zu überblicken.

Coda
2008-08-12, 05:31:05
Manche Leute müssen aber auch einfach echt überall ihren blöden Senf abgeben.

Der_Donnervogel
2008-08-12, 13:44:40
Ja, das ist hier wirklich am Thema vorbei. Die Frage was "leserlicher" und/oder "guter" C-Quellcode ist, müsste man sowieso in einem eigenen Thread diskutieren, denn da gehen die Meinungen auch weit auseinander.

Um wieder mehr auf das eigentliche Threadthema zurückzukommen, das Problem mit dieser Art der Konvertierung ist, dass man damit sehr schnell Fehler macht. Natürlich kann man versuchen dem mit Konventionen entgegenzuwirken, aber gefährlich bleibt die Sache allemal. Wobei man natürlich auch bei VB ziemlich wilde Sachen machen kann, vor allem wenn man in die implizite Typkonvertierung auch noch Strings mit einbezieht. VB versucht ja auch automatisch Strings zu parsen um zu schauen ob die eine Zahl enthalten und rechnet dann damit weiter.