Darmowy kurs Java

Konwersja i Rzutowanie typów

Konwersja typów matematycznych

Zdarza się tak, że jeśli w jednej ze zmiennych przechowujemy jakieś dane typu A, to w pewnym momencie potrzebujemy tych samych danych, ale już w typie B. Najprostszy przykład, to taki, w którym mamy liczbę zadeklarowaną jako int, a następnie chcemy ją podzielić także przez typ int. Jak wiemy z wcześniejszych lekcji kursu będziemy mieli wtedy do czynienia z dzieleniem całkowitym i otrzymamy fałszywe wyniki. Oczywiście są pewne zasady, które można przedstawić w 4 prostych punktach:

  • Jeśli jeden z operandów jest typu double, to drugi także zostanie zamieniony na double
  • Lub, jeśli któryś z operandów jest typu float to drugi także zostanie zamieniony na float
  • Lub, jeśli któryś z operandów jest typu long, drugi także zostanie zamieniony na long
  • Gdy żadne z wyższych nie występuje oba typy zostaną zamienione na int

W skrócie możemy sobie wyobrazić, że przy działaniach matematycznych wszystkie zmienne są automatycznie konwertowane przez wirtualną maszynę Javy na najwyższy dostępny typ.

public class Konwersje{
  public static void main(String[] args){
	  int a = 5;
	  double b = 13.5;
	  double c = b/a;
	  System.out.println(c);
  }
}

Widzimy to działanie w powyższym przykładzie. Najpierw deklarujemy dwie zmienne a i b, odpowiednio typów int, oraz double. Następnie do zmiennej c przypisujemy wynik działania b/a. Czego się spodziewać w takiej sytuacji?

Przed podzieleniem typ zmiennej 'a' jest konwertowany na double dzięki czemu otrzymamy wynik zmiennoprzecinkowy, a nie całkowitoliczbowy. Należy uważać, aby nie popełnić błędu i nie próbować wymusić konwersji "w dół", czyli na przykład z typu double na int. Spowoduje to, że programu nie uda się nam skompilować.

public class Konwersje{
  public static void main(String[] args){
	  int a = 5;
	  double b = 13.5;
	  int c = b/a;               //TAK NIE MOŻNA ZROBIĆ!
	  System.out.println(c);
  }
}

W powyższym przykładzie próbujemy przypisać do zmiennej c typu int wynik ilorazu b/a, którym jest liczba zmiennoprzecinkowa 2.7. W takim wypadku kompilator zaprotestuje.

No dobrze, ale co zrobić, gdy faktycznie potrzebujemy zamienić typ double na int?

Rzutowanie (jawna konwersja)

Rzutowanie jest w przeciwieństwie do konwersji jawne i mamy na nie wpływ. Możemy wymusić konwersję z jednego typu na inny umieszczając uprzednio w okrągłych nawiasach typ docelowy.

	  int a = 5;
	  double b = 13.5;
	  int c = (int)b/a;

W takim wypadku błędu już nie będzie. Jednak musimy zdawać sobie sprawę, że takie postępowanie niesie ze sobą utratę części danych, w tym wypadku ucięcie części ułamkowej. W powyższym przykładzie najpierw następuje dzielenie, a następnie ucięcie(nie zaokrąglenie) wyniku. Aby otrzymać przybliżoną wartość wyniku należałoby użyć metody Math.round().

Konwersję możemy więc przedstawić jako niejawne rzutowanie:

	  int a = 5;
	  double b = 13.5;
	  double c = b/(double)a;

Na szczęście nie musimy tego zapisywać. Java zrobi to za nas automatycznie.

Zadania do samodzielnego wykonania:

1.6 Wykorzystaj konwersję i rzutowanie wypróbuj zamiany różnych typów prostych między sobą. Szczególną uwagę zwróć na rzutowanie char na int. Jak myślisz, co w ten sposób otrzymujesz?

Rozwiązanie

Komentarze

Dodawanie komentarzy jest aktualnie wyłączone.

Marcin

Mały przykład konwersji typów: kod: public class ASCII{ public static void main(String[] args){ char znak; for(int i = 0; i < 256;){ ++i; znak = (char)i; System.out.print(i+" to "+znak+" "); } } }

Witek

Inny przykład konwersji : public class Demonstracja_Rzutowania { /** * Napisz program przedstawiający niektóre typy rzutowania i konwersji * Wyniki przedstaw na konsoli * */ public static void main(String[] args) { double x = 15.0, y = 5.0; byte b; int i; char ch,ch1; // rzutowanie z double do int i = (int) (x/y); System.out.println("Wynik x/y oraz rzutowania do int to: " + i); // rzutowanie z int do byte i = 129; b = (byte) i; //zakres typu byte : -128 do 127 System.out.println("Wynik rzutowania int do byte to: " + b); // rzutowanie z byte do char b = 67; ch = (char) b; System.out.println("Wynik rzutowania z byte do char to: " + ch); System.out.println(); b = 10; // byte i = b * b; // daje nam typ int System.out.println("Wynik rzutowania jest typu int: " + i); b = 9; b = (byte)(b * b); // rzutujemy spowrotem do typu byte System.out.println("Wynik rzutowania jest teraz typu byte: " + b); ch = 'A'; ch1 = 'h'; ch = (char)(ch + ch1); System.out.println("Wynik rzutowania typu char z powrotem do typu char to: " + ch); } }

NBT

"Rzutowanie (jawna konwersja) Rzutowanie jest w przeciwieństwie do konwersji jawne i mamy na nie wpływ." Czyż nie powinno być: "Rzutowanie jest przeciwieństwem konwersji niejawnej, to znaczy, że mamy na nie wpływ"?

alfa

Dziwne to, taki prosty program : public class KonwersjeAndRzutowanieTypów { public static void main(String[] args) { int a = 3; double b = 10; double c = b / a; System.out.println(c); } } W wyniku dostaje: 3.3333333333333335, skąd ta piątka na końcu, powinny być same trójki :/

Luigi

int c = (int)b/a; "W powyższym przykładzie najpierw następuje dzielenie, a następnie ucięcie(nie zaokrąglenie) wyniku." Nie do końca - operator rzutowania ma wyższy priorytet, więc najpierw następuje zrzutowanie zmiennej b do typu int, a następnie dokonane jest dzielenie liczb całkowitych :)

Jakub

Chcemy zrzutować (a+a*a),(gdzie a jest typu double) na int double a; int c=(int)(a+a*a);// czy może ma być int c=(int)a+(int)a*(int)a;

SAK

Może być i tak i tak, ale wyjdą różne wyniki (przy znaczeniach a double)

ssss

Bardzo przystępnie wytłmaczone ;-)

mario

import java.util.Scanner; public class tablice2 { /** * @param args */ public static void main(String[] args) { System.out.println("Podaj liczbe"); Scanner odczyt = new Scanner(System.in); int n = odczyt.nextInt(); int[] tablica = new int[n]; for(int i = n;i>0;i--){ tablica[i]=i+1; } while(n>0){ System.out.println(tablica[n]); n++; } } } a tak czemu nie dziala?

Marcin Kunert

Na pierwszy rzut oka masz błąd w pętli. Zamiast i- powinno być raczej i--.

lolo

Mario na samej górze i tak samo pod polem do wpisywania komentarzy dostępny jest link do forum JavyStart. Taka mała uwaga tam lepiej jest zadawać pytania razem z kodem gdyż system komentarzy przekształca niektóre rzeczy podczas wysyłania np. cudzysłowie. Co trochę utrudnia pomoc. Dobrze a teraz odnośnie kodu. 1.Jak to Marcin napisał już w linijce for(int i = n;i>0;i–){ powinien być podwójny minus(możliwe, że masz w kodzie ten podwójny minus i tylko system zamienił podczas wysyłania o czym wspomniałem wyżej) 2. Wstaw po linijce int[] tablica = new int[n]; n=n-1; i powinien program już zacząć działać bez zwracania błędów. 3. I mała rada zmień w linii for(int i = n;i>0;i–){ warunek i>0 na i>=0 oraz w linii while(n>0){ warunek n>0 na n>=0 bo wydaje mi się, że o to Ci chodziło.

Chłopek

<pre class="brush: java; gutter: true"> //Chyba nie rozumiesz indeksowania tablic jeszcze ;) for(int i = n;i&gt;0;i- -){ tablica[i-1]=i+1; } while(n&gt;0){ // Też błąd był, bo miałeś n++ co zawsze jest &gt; 0, a po drugie indeksowanie tavblic zaczyna się od ZERA, więc np. w tablicy ośmioelementowej nie będzie indeksu nr 8. Ostatni to 7, a pierwszy to nr 0 ;) System.out.println(tablica[- -n]); }</pre>

Artur

Tyle glow i naprawde nikt nie zauwazyl jeszcze bledu. W pierwszym przykladzie dzielisz a/b i w drugim robisz to samo a/b zamiast b/a, drobny blad ale dla takich laikow jak ja to juz jest klopot z interpretacja.

Artur

Odwrotnie b/a zamiast a/b.

Sławek Ludwiczak

poprawione, dzięki :)