# Typkonvertierung



## Wang (24. Nov 2009)

Hallo, liebe JAVA-Freunde! 

Ich bitte um eine Durchsicht meiner Lösung zu Teilaufgabe (a).
Zunächst die Aufgabe selbst:







Lösung (a):

Ausdruck			           Typ	Wert					Begruendung

(b1 * i1) / (f1 * 3.0f)
float
(99 * 9) / (2.0f * 3.0f) = 148.5
es wird explizit von einem schmäleren Typ in einen breiteren Typ konvertiert

"1 + 2 + 3 = " + (i1 - 3)
int
"1 + 2 + 3 = 6" + (9 - 3) = 12
der Datentyp int wird während des Vorgangs nicht konvertiert und bleibt somit unverändert

d1 / f1 + i1
float
0.222 / 2.0f + 9 = 9.111
es wird explizit vom breiteren Typ double in den schmäleren Typ float konvertiert

c1 * c2
int
'!' * 'a' = 3201
jedes Zeichen wird durch einen bestimmten Wert repräsentiert und hier wurden die Zeichen '!' und 'a' in Zahlen umgewandelt und miteinander multipliziert

i1 + str1 + l2
long
1 + "123" + 123L = 1123123
es wurde explizit in den Typ long konvertiert


Ich bin für jedes Feedback wirklich sehr dankbar! :toll:


----------



## Wang (24. Nov 2009)

Teilaufgabe (b) habe ich so gelöst:

Begründung:
Mit byte-, short- und char-Werten werden in Java in der Regel keine Verknüpfungen zu Ausdrücken durchgeführt.
Operanden dieser Typen werden vor der Verknüpfung mit einem Operator in den Datentyp int konvertiert.
Man bezeichnet diesen Vorgang als Integer-Erweiterung.

So lässt sich das Problem beheben:

statt:
byte b3 = b1 + b2;

schreibe:
int b3 = b1 + b2;


Passt die Begründung und die Lösung des Problems soweit?

Vielen Dank.


----------



## Marco13 (24. Nov 2009)

Zu a ein Tipp: Strings werden nicht "ausgerechnet". 
Und zu b - passt, aber es gibt noch eine Alternative:
byte b3 = .... ??? ...


----------



## RaoulDuke (24. Nov 2009)

Sind das gescannte Hausaufgaben?


----------



## Wang (24. Nov 2009)

Marco13 hat gesagt.:


> Zu a ein Tipp: Strings werden nicht "ausgerechnet".
> Und zu b - passt, aber es gibt noch eine Alternative:
> byte b3 = .... ??? ...



Danke, Marco13.

Bezüglich (a). Wenn ich das hier laufen lasse:


```
public class Test
{
   public static void main (String[] args)
   {
      int x = 1;
      long y = 123;
      
      System.out.print (x + "123" + y);
   }
}
```

erhalte ich genau 1123123.
Ist meine Lösung richtig, wenn ich das Ergebnis so setze "1123123"?

Bezüglich der (b):

Meinst du vielleicht?
byte b3 = (int) b1 + (int) b2;

Falls ja, dann haut das bei mir so nicht hin:


```
public class Test
{
   public static void main (String[] args)
   {
      byte b1 = 99;
      byte b2 = 2;
      byte b3 = (int) b1 + (int) b2;
      System.out.print (b3);
   }
}
```


----------



## Marco13 (25. Nov 2009)

Zur a: Da hattest du
_
1 + "123" + 123L = 1123123
es wurde explizit in den Typ long konvertiert
_

Aber 1+123+123 ist nicht 247 (als long), sondern eben 1123123 als ...?


Und die b) : Casten ist schon der richtige Ansatz...


----------



## Wang (25. Nov 2009)

Marco13 hat gesagt.:


> Aber 1+123+123 ist nicht 247 (als long), sondern eben 1123123 als ...?



Danke, Marco13 für deine Geduld.
Das kann ja dann nur der Typ String sein?

Bearbeitung der Lösung:

i1 + str1 + l2
String
1 + "123" + 123L = "1123123"
mindestens einer der Operanden ist ein String, somit wird der gesamte Ausdruck als String-Konkatenation ausgeführt



Marco13 hat gesagt.:


> Und die b) : Casten ist schon der richtige Ansatz...



Nach langem Probieren, würde ich sagen:
byte b3 = byte (b1 + b2);

Aber ich bin jetzt wirklich verwirrt. ???:L
Zwei Dinge bereiten mir Kopfschmerzen:

1.) Warum muss man, obwohl man den Datentyp von b1 und b2 am Anfang bereits festgelegt hat, den Datentyp für b1 + b2 explizit festlegen?
2.) Warum akzeptiert der Compiler das in der Form 
	
	
	
	





```
byte b3 = (byte) b1 + (byte) b2;
```
 nicht, allerdings in der Form 
	
	
	
	





```
byte b3 = (byte) (b1 + b2)
```
 schon?

Vielen Dank!


----------



## deroberdon (25. Nov 2009)

Wang hat gesagt.:


> Hallo, liebe JAVA-Freunde!
> d1 / f1 + i1
> float
> 0.222 / 2.0f + 9 = 2.111
> es wird explizit vom breiteren Typ double in den schmäleren Typ float konvertiert



wo steht denn, dass es konvertiert wird? ich hätte einfach alles in double umgewandelt und gut is?^^
aber bitte klär mich auf


----------



## Marco13 (25. Nov 2009)

Etwas vereinfacht ausgedrückt: Egal wie man byte, short oder char mit + und - verrechnet: Das Ergebnis ist erstmal vom Typ int. 

Das was deroberdon angesprichen hat stimmt auch (also, ist bei dir noch falsch)


----------



## Wang (25. Nov 2009)

Danke.

Ich dachte die explizite Typkonvertierung erfolgt durch das 2.0f ?

Zumindest gemäß diesem Programm hier, denn lasse ich das f weg, meckert der Compiler... 


```
public class Test
{
   public static void main (String[] args)
   {
      double x = 0.222;
      float y = 2.0f;
      int z = 9;
      System.out.println (x/y+z);
   }
}
```

Ich glaube, diese Lösung stimmt auch nicht ganz:


```
"1 + 2 + 3 = " + (i1 - 3)
int
"1 + 2 + 3 = 6" + (9 - 3) = 12
der Datentyp int wird während des Vorgangs nicht konvertiert und bleibt somit unverändert
```

Eigentlich müsste es doch heißen:


```
"1 + 2 + 3 = " + (i1 - 3)
int
"1 + 2 + 3 = " + (9 - 3) = 6
der Datentyp int wird während des Vorgangs nicht konvertiert und bleibt somit unverändert
```


----------



## Marco13 (25. Nov 2009)

_
Ich dachte die explizite Typkonvertierung erfolgt durch das 2.0f ?
Zumindest gemäß diesem Programm hier, denn lasse ich das f weg, meckert der Compiler... 
_

Das angehängte "f" ist keine "Konvertierung" in diesem Sinne - das ist nur eine ""Markierung"", die besagt, dass das ein float sein soll. Entscheidend für die Aufgabe ist so wie ich das sehe der Typ des _gesamten_ ausdrucks - also praktisch die Frage, was bei
[TYP] x = [DerAusdruck]
an Stelle von "[TYP]" stehen muss (dass ist so etwas vereinfacht und unpräzise beschrieben, aber von der Idee her...)




_Ich glaube, diese Lösung stimmt auch nicht ganz:_

Mein Hinweis darauf, dass Strings nicht ausgerechnet werden, bezog sich auf mehrere Ausdrücke


----------



## Wang (25. Nov 2009)

Danke, Marco13. 

Wozu wird das mit der Markierung f eigentlich gemacht? ???:L

Jetzt bin ich aber mit meinem JAVA echt langsam am Ende...
Das von der oberdon angesprochene Beispiel müsste doch dann so richtig sein:


```
d1 / f1 + i1
double
0.222 / 2.0f + 9 = 9.111
es wird implizit in den schmäleren Typ float konvertiert
```

ABER: dagegen spricht doch das Ergebnis, welches nicht vom Typ double sondern vom Typ float ist: 9.111.


Das erste Beispiel habe ich dann wohl auch falsch.
Denn anstatt


```
(b1 * i1) / (f1 * 3.0f)
float
(99 * 9) / (2.0f * 3.0f) = 148.5
es wird explizit von einem schmäleren Typ in einen breiteren Typ konvertiert
```

müsste es denke ich


```
(b1 * i1) / (f1 * 3.0f)
double
(99 * 9) / (2.0f * 3.0f) = 148.5
es wird implizit von einem schmäleren Typ in einen breiteren Typ konvertiert
```

heißen?

Sorry, wenn ich einfach nicht auf die richtigen Ergebnisse komme, aber ich mache das bestimmt nicht mit Absicht...
Vielen Dank für Euren Support!


----------



## Marco13 (25. Nov 2009)

Ich bin auch langsam nicht mehr sicher, ob da irgendwie ein Mißverständnis vorliegt:


```
d1 / f1 + i1
double
0.222 / 2.0f + 9 = 9.111
es wird implizit in den schmäleren Typ float konvertiert
```

Das "double" hätte ich jetzt interpretiert als: "Das Egebnis ist vom Typ double" - war das nicht so gemeint?
Und wenn das so gemeint war, passt das nicht zu der Aussage, dass "implizit auf float konvertiert wird". Konvertiert wird da nichts. Insbesondere wird, wenn etwas "implizit" konvertiert wird, immer in einen "größeren" Typ konvertiert - wie genau, kann man unter Conversions and Promotions nachlesen  





_Das erste Beispiel habe ich dann wohl auch falsch._

Ne, das müßte eigentlich gestimmt haben... 

```
(b1 * i1) / (f1 * 3.0f)
float
(99 * 9) / (2.0f * 3.0f) = 148.5
```
Als Begründung würde ich sowas schreiben wie 
Linke Klammer: byte * int = int
Rechte Klammer: float * float = float
Gesamt: int / float = float

Du solltest vielleicht auch mal ein bißchen rumprobieren ... solche Aufgaben sind vermutlich gar nicht dafür gedacht, "aus dem Kopf" und "auswendig" "mit Bleistift und Papier" gemacht zu werden. Als Beispiel für's erste:

```
class TypeTest
{
    public static void main(String args[])
    {
        double d1 = 0.222;
        float f1 = 2.0f;
        int i1 = 9;

        // float result = d1 / f1 + i1; // Geht nicht

        double result = d1 / f1 + i1;
        System.out.println(result);
    }

}
```


----------



## Wang (26. Nov 2009)

Ein großes THANKS an Dich, Marco13 für deine Geduld und für deine Hilfe! :toll:

Ich habe jetzt das so hingeschrieben:


```
d1 / f1 + i1
double
0.222 / 2.0f + 9 = 9.111
double / float = double + int = double
```

Falls du Zeit und Lust hast, wäre es super, wenn du nochmals einen Blick auf die anderen Beispiele werfen kannst:


```
"1 + 2 + 3 = " + (i1 - 3)
int
"1 + 2 + 3 = " + (9 - 3) = 6
der Datentyp int wird während des Vorgangs nicht konvertiert und bleibt somit unverändert
```


```
c1 * c2
int
'!' * 'a' = 3201
jedes Zeichen wird durch einen bestimmten Wert repräsentiert und hier wurden die Zeichen '!' und 'a' in Zahlen umgewandelt und miteinander multipliziert
```


```
i1 + str1 + l2
String
1 + "123" + 123L = "1123123"
mindestens einer der Operanden ist ein String, somit wird der gesamte Ausdruck als String-Konkatenation ausgeführt
```

Passt das so aus deiner Sicht?

Sorry, wenn ich so penibel wirke und die Beispiele nochmals einzeln aufliste, aber als Anfänger versuche ich nur, eine halbwegs ordentliche Struktur zu schaffen...


----------



## Marco13 (26. Nov 2009)

Versuch' mal einen Codeschnispel wie oben zu schreiben, wo
int result = "1 + 2 + 3 = " + (9 - 3);
drinsteht....


EDIT: Du hattest hier irgendwo auch die Aufgabe mit den... Typen und Sorten und den Ableitungen gepostet, wo Andrey dir dann grob erklärt hat, wie man diesen "Ableitungsbaum" erstellt. Versuch' vielleicht mal, da ein paar Parallelen zu ziehen


----------



## Wang (26. Nov 2009)

Danke, Marco13.

Sind die anderen Beispiele soweit richtig?

Hier der Codeschnipsel:


```
class TypeTest
{
    public static void main(String args[])
    {

        int i1 = 9;

        // int result = "1 + 2 + 3 = " + (i1 - 3); // Geht nicht

        int result = (i1 - 3);
        System.out.println("1 + 2 + 3 = " + result);
    }
}
```

Ist diese Lösung dann richtig:


```
"1 + 2 + 3 = " + (i1 - 3)
String
"1 + 2 + 3 = " + (9 - 3) = "1 + 2 + 3 = 6"
der Ausdruck in der Klammer wird zunächst ausgerechnet und dann im vorhandenen String ausgegeben
```

Ich fürchte, mir fehlt noch der Blick für's Detail...


----------



## Marco13 (26. Nov 2009)

Das letzte stimmt dann wohl. Bei den übrigen habe ich den Überblick über den jeweils aktuellen Stand verloren, aber ausprobieren kann da hilfreich sein...


----------



## Wang (26. Nov 2009)

Danke, Marco13.

Ich werde diese Aufgabe dann langsam aber sicher abschließen.
Bitte nur noch um einen kurzen Kommentar bezüglich dieses Beispiels, ob das aus Deiner Sicht passt (vor allem die Begründung):


```
c1 * c2
int
'!' * 'a' = 3201
jedes Zeichen wird durch einen bestimmten Wert repräsentiert und hier wurden die Zeichen '!' und 'a' in Zahlen umgewandelt und miteinander multipliziert
```


----------



## Marco13 (26. Nov 2009)

Naja, ein char ist auch eine "Zahl" - "Zahl" ist in bezug auf Typen so nichtssagend... Als Begründung dafür, dass "int" rauskommt, kannst du "Java Language Specification Section 5.6.2" angeben: Conversions and Promotions


----------



## Wang (26. Nov 2009)

Marco13 hat gesagt.:


> Naja, ein char ist auch eine "Zahl" - "Zahl" ist in bezug auf Typen so nichtssagend... Als Begründung dafür, dass "int" rauskommt, kannst du "Java Language Specification Section 5.6.2" angeben: Conversions and Promotions



Sorry, aber ich kann das, was unter dem Link steht, gedanklich nicht wirklich mit dem Typ char in Verbindung bringen, sonst würde ich das natürlich sofort als Begründung verwenden...


----------



## Marco13 (26. Nov 2009)

Dort steht
_
When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order, using widening conversion (§5.1.2) to convert operands as necessary:

    * If any of the operands is of a reference type, unboxing conversion (§5.1.8) is performed. Then:
    * If either operand is of type double, the other is converted to double.
    * Otherwise, if either operand is of type float, the other is converted to float.
    * Otherwise, if either operand is of type long, the other is converted to long.
    * *Otherwise, both operands are converted to type int. *
_
Das letzte trifft bei einer Rechnung wie char*char zu, weil ... keine der vorherigen Regeln zutrifft: Es kommt kein Referenztyp, kein double, kein float und kein long drin vor.... Also werden beide zu ints gemacht, und dann losgerechnet...


----------



## Wang (2. Dez 2009)

Kurze Rückmeldung:
Gemäß Musterlösung ist alles richtig. 

Vielen Dank für den starken Einsatz!


----------

