Autor Beitrag
Christoph1972
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 690
Erhaltene Danke: 16


VS2015 Pro / C# & VB.Net
BeitragVerfasst: Mo 13.07.09 17:01 
Hallo zusammen,


ich wunder mich gerade über den C# Compiler. Beispiel C#:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
private void button1_Click(object sender, EventArgs e)
{
 Double a = button1.Height; // 23
 Double b = button1.Width; // 75

 Double test1 = a / b;//= 0.30666666666666664  Prima!

 Double test2 = button1.Height / button1.Width; // = 0  warum das? 

 Int32 test3 = button1.Height / button1.Width; // = 0 warum wird das nicht vom Compiler bemängelt?
}



Beispiel VB.Net: (es gibt leider keine Bereiche für VB.Net)
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
Option Strict = On

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim a As Double = Button1.Height
Dim b As Double = Button1.Width

Dim test1 As Double = a / b 'passt

Dim test2 As Double = Button1.Height / Button1.Width '
passt

Dim test3 As Int32 = Button1.Height / Button1.Width ' hier setzt der Compiler den Rotstift an, prima

End Sub


Kann mir mal bitte jemand erklären was hier los ist? C# ist doch Type-Sicher, das darf doch nicht sein, oder?



Gruß
völlig durcheinander Christoph
JasonDelife
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 81

Windows 7 Professional
C# (Visual Studio 2008 Professional), Java (NetBeans IDE 6.7)
BeitragVerfasst: Mo 13.07.09 17:23 
int / int = int

Grüße, JasonDelife.
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mo 13.07.09 17:24 
Mal sehen, was die Hilfe dazu meint ;) ...
/ Operator (C# Reference) hat folgendes geschrieben:
When you divide two integers, the result is always an integer. For example, the result of 5 / 2 is 2. To determine the remainder of 5 / 2, use the modulo operator (%). To obtain a quotient as a rational number or fraction, give the dividend or divisor type float or type double. You can do this implicitly by putting a decimal point after the number, as shown in the following example. [...]

Bei zwei Variablen musst du eine zuvor nach float/double casten.

_________________
>λ=
Christoph1972 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 690
Erhaltene Danke: 16


VS2015 Pro / C# & VB.Net
BeitragVerfasst: Mo 13.07.09 17:52 
user profile iconJasonDelife hat folgendes geschrieben Zum zitierten Posting springen:
int / int = int


Hm, da finde ich den VB.Net Compiler aber besser, da int / int oft != int . Wenn man da nicht aufpasst, so wie ich, dann gibt das unbrauchbare Ergebnisse. Habt ihr ein Glück das ich keine Steuerung für ein Atomkraftwerk geschrieben habe. Ich habe in der letzten Zeit geglaubt das solche fehler nur mit z.B. VB 1-6.0 möglich sind, da nicht Type-Sicher. Mit VB.Net & Option Strict = On kann das nicht passieren.

Vielen Dank erstmal, wieder was gelernt.

Gruß
Christoph
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Mo 13.07.09 19:14 
user profile iconChristoph1972 hat folgendes geschrieben Zum zitierten Posting springen:
Hm, da finde ich den VB.Net Compiler aber besser, da int / int oft != int .

Das ist Ansichtssache. Wenn ich "5 durch 2" teile, dann geht es genau genommen nur 2 Mal auf. Wenn (wie oben zitiert) "/" so definiert ist, dass der Ergebnis-Typ gleich den Ausgangstypen ist, dann ist das eben so.

user profile iconChristoph1972 hat folgendes geschrieben Zum zitierten Posting springen:
Wenn man da nicht aufpasst, so wie ich, dann gibt das unbrauchbare Ergebnisse. Habt ihr ein Glück das ich keine Steuerung für ein Atomkraftwerk geschrieben habe.

In der Tat. Wenn jemand nicht aufpasst bei dem, was er macht, und nicht nach den aktuellen gültigen Regeln (nämlich den C#-Regeln) handelt, dann ...

user profile iconChristoph1972 hat folgendes geschrieben Zum zitierten Posting springen:
Ich habe in der letzten Zeit geglaubt das solche fehler nur mit z.B. VB 1-6.0 möglich sind, da nicht Type-Sicher. Mit VB.Net & Option Strict = On kann das nicht passieren.

Das ist eben kein Fehler, sondern so vorgesehen. Also weiß ich wirklich nicht, worüber du dich aufregst. Jürgen
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mo 13.07.09 19:26 
C# und VB mit Strict=On sind gleich typ(un)sicher, erstere Sprache hat für das Problem eben die Operatorüberladung gewählt, letztere zwei getrennte Operatoren. In einer "wirklich typsicheren" Sprache wäre das Problem trotz Überladung nicht aufgetreten, da sie die Zuweisung von button1.Height / button1.Width an double test2 verweigert hätte.
Ob nun überladener Operator oder zwei davon, ob absolut typsicher oder mit impliziten Casts, das läuft letztendlich quasi auf Geschmackssache hinaus ;) .

_________________
>λ=
Christoph1972 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 690
Erhaltene Danke: 16


VS2015 Pro / C# & VB.Net
BeitragVerfasst: Mo 13.07.09 22:27 
user profile iconJüTho hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconChristoph1972 hat folgendes geschrieben Zum zitierten Posting springen:

Also weiß ich wirklich nicht, worüber du dich aufregst. Jürgen



Ich habe mich nur gewundert, aufgeregt nicht :zwinker: Normalerweise wandelt man ja auch immer um, deshalb habe ich das erst nach ca. 6 Monaten C# bemerkt, war ehr Zufall.


Also, vielen Dank!
Christoph1972 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 690
Erhaltene Danke: 16


VS2015 Pro / C# & VB.Net
BeitragVerfasst: Sa 25.07.09 09:27 
Hi,


ich habe gerade bemerkt das der Compiler bei Int16 eine Meldung rausgibt, das der Typ nicht impliziet konvertiert werden kann. Das muss ich nicht verstehen, oder? Das finde ich inkonsequent, aber nun ja......weiter gehts mit den "wichtigen" Dingen.



Gruß
Christoph
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Sa 25.07.09 12:23 
Eine... sehr präzise Problembeschreibung :gruebel: . Du meinst wahrscheinlich die Tatsache, dass die 8- und 16-Bit-Typen keine eigenen arithmetischen Operatoren besitzen, ergo short + short = int.
Und das ist so, weil, äh... :mrgreen:
Erstens rechnet die gesamte CLI so: IL Instructions gibt es einfach nur für 32-Bit, 64-Bit und Floats. Das dürfte vor allem damit zusammenhängen, dass es auf einer modernen CPU keinen Grund gibt, mit kleineren Typen zu rechnen, also Performance.
Zweitens ist es ein C-Erbe, um Overflow-Bugs zu vermeiden. Bei Int32 ist die Gefahr eben einfach etwas geringer ;) .

Zusammengefasst (so verstehe ich jedenfalls Eric Lipperts Kommentar hier): (S)Byte und (U)Int16 sind in .NET nicht zum Rechnen, sondern nur zum Speichern da.

_________________
>λ=
InCoBra
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 43



BeitragVerfasst: Sa 25.07.09 12:24 
Mit Int16 meinst du das wie folgt?

ausblenden C#-Quelltext
1:
2:
3:
Int32 Zahl1 = 26;
Int32 Zahl2 = 16;
Int16 Zahl  = Zahl1 / Zahl2;


Falls ja ist die Erklärung recht einfach:

Int16 hat: Min/Max-Value: -32767 / +32767
Int32 hat: Min/Max-Value: -2147483647 / +2147483647

Das ist also wie als wenn du versuchst eine Zahl aufzuschreiben, die 10 Stellen hat, du hast aber nur Platz für 5 Stellen...


// Zu langsam gewesen...
Christoph1972 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 690
Erhaltene Danke: 16


VS2015 Pro / C# & VB.Net
BeitragVerfasst: Sa 25.07.09 23:33 
Hi zusammen,


ich meinte eigentlich:

Int16 / Int16 = Kompiler Message das nicht impliziet konvertiert werden kann.

bei

Int32 / Int32 = Keine Message, der Rest wird einfach abgeschnitten.


Ok, der Int16 ist nicht zum Rechnen vorgesehen, aber der User=ich kann es trotzdem. Von daher wundert es mich, das der Compiler hier unterschiedlich handelt. Wie gesagt, mit VB.Net ist das nicht möglich, was ich auch gut finde da: Int / Int = oft falsch.


Gruß
Christoph