4. Działania matematyczne
Wiemy już dość dużo o operacjach arytmetycznych. Warto jednak zwrócić krótko uwagę na dwie kwestie:
- specjalne wartości dla liczb typu double,
- "bibliotekę" funkcji matematycznych.
Jeżeli zdarzy się nam w programie podzielić liczbę całkowitą przez całkowite
zero, to powstanie wyjątek (sygnał o błędzie) ArithmeticException.
Całkiem inaczej jest w przypadku liczb rzeczywistych.
Dzielenie przez zero nie powoduje błędu, ale daje w wyniku specjalną wartość,
reprezentującą nieskończoność. Wartości +- nieskończoność są dostępne jako
statyczne stałe klasy Double: Double.POSITIVE_INFINITY i Double.NEGATIVE_INFINITY.
Dzięli temu łatwo możemy wykryć przypadek dzielenia przez zero.
Inną specjalną wartością typu rzeczywistego jest NaN ("Not-a-Number" - nie-liczba.
liczba nie zdefiniowana). Reprezentuje ona wyniki pewnych operacji arytmetycznych
(takich jak np. 0.0 / 0.0). W klasie Double zdefiniowano stałą statyczną NaN. Ale nie powinna ona być wykorzystywana do sprawdzania czy wynik operacji
jest "Not-a-Number", bowiem wartości Nan mają ciekawą własciwość: NaN !=
Nan.
Do sprawdzania czy wartość jest Nan czy nie należy używac metody isNan z klasy Double.
Przykładowy program ilustruje wyżej powiedziane:
public class InfNan {
public static void main(String[] args) {
double d = 1.0 / 0.0;
System.out.println("d = " + d);
if (d == Double.POSITIVE_INFINITY)
System.out.println("to jest + nieskończoność");
d = -1.0 / 0.0;
System.out.println("d = " + d);
if (d == Double.NEGATIVE_INFINITY)
System.out.println("to jest - nieskończoność");
d = 0.0 / 0.0;
System.out.println("d = " + d);
if (d == Double.NaN)
System.out.println("to nie jest liczba");
else System.out.println("to jest liczba");
Double dd = new Double(d);
System.out.println("naprawdę: to nie jest liczba ? - " + dd.isNaN());
}
}
Wynik działania programu:
d = Infinity
to jest + nieskończoność
d = -Infinity
to jest - nieskończoność
d = NaN
to jest liczba
naprawdę: to nie jest liczba ? - true
W klasie Math pakietu java.lang zdefiniowano statyczne metody matematyczne.
Między innymi:
Metody matematyczne
|
int abs(int arg) | wartość bezwzględna argumentu | double abs(double arg) |
|
int min(int arg1, int arg2) | minimum z arg1, arg2 | double min(double arg1, double arg2) | minimum z arg1, arg2 | int max(int arg1, int arg2) | maksimum z arg1, arg2 | double max(double arg1, double arg2) | maksimum z arg1, arg2 | double sqrt(double arg) | pierwiastek kwadratowy arg
| double exp(double arg) | zwraca potęgę o podstawie e i wykładniku arg | double pow(double base, double exp) | zwraca potęgę o podstawie base i wykładniku
exp. Jeśli base ma wartość 0, a exp jest ujemne albo niecałkowite, to zwraca
NaN. | double log(double arg) | zwraca logarytm naturalny arg. Jeśli argument nie jest dodatni, tozwraca NaN. | double sin(double arg) | zwraca sinus argumentu podanego w radianach. | double cos(double arg) | cosinus | double tan(double arg) | tangens |
Proszę zapoznać się z dokumentacją klasy Math.
W klasie Math znajduje się również generator liczb pseudolosowych - metoda
random. Jej użycie jest jednak mniej wygodne niż użycie niestatycznych metod klasy Random, znajdującej się w pakiecie java.util.
Generator liczb pseudolowowych należy najpierw zainicjować za pomocą konstruktorów klasy Random:
Random() // inicjuje generator na podstawie aktualnego czasu w milisekundach
Random(long seed) // inicjuje generator na podstawie podanej liczby
Następnie można generować kolejne liczby pseudolosowe za pomocą odpowiednich niestatycznych metod np:
double nextDouble()
zwraca kolejną pseudolosową liczbę rzeczywistą z równomiernego rozkładu w przedziale [0,1]
int nextInt(int n)
zwraca kolejną pseudolosową liczbę całkowitą z równomiernego rozkładu w przedziale [0, 1) tj. 0 <= nextInt(n) < n.
Zadanie: napisać program do losowania liczb w totolotku (6 z 49).
Umożliwić - na życzenie - inicjowania generatora na podstawie sumy podanych przez użytkownika liczb.
Uwaga: uwzględnić to, że w jednym losowaniu liczby nie mogą się powtarzać.
Przed lekturą dalszego tekstu proszę to zadanie rozwiązać samodzielnie
Możliwe rozwiązanie.
import javax.swing.*;
import java.util.*;
public class Toto {
public static void main(String[] args) {
String msg = "Podaj magiczne liczby,\n" +
"nic nie wpisuj = automatyczna inicjacja,\n" +
"lub wybierz Cancel, by skończyć losowania";
Random rand;
boolean[] isDrawn = new boolean[49]; // i-ty element tablicy
// ma wartość true
// gdy liczba i została wylosowana
String inp;
while ((inp = JOptionPane.showInputDialog(msg)) != null) {
if (!inp.equals("")) { // inicjacja generatora sumą podanych liczb
StringTokenizer st = new StringTokenizer(inp);
long sum = 0;
while (st.hasMoreTokens()) {
String slicz = st.nextToken();
sum += Integer.parseInt(slicz);
}
rand = new Random(sum);
}
else rand = new Random(); // gdy nic nie podano - inicjacja czasem
// Losowanie
// Jeszcze żadna liczba nie została wylosowana:
for (int i=0; i < isDrawn.length; i++) isDrawn[i] = false;
final int ILE = 6; // liczb do wylosowania
int k = 0; // licznik niepowtarzających się liczb
System.out.print('\n');
while (k < ILE) {
int n = rand.nextInt(49); // losowanie: 0 <= n < 49
if (isDrawn[n]) continue; // jeżeli ta liczba już była wylosowana
else { // nie była - bierzemy ją!
k++; // licznik wziętych + 1
isDrawn[n] = true; // teraz jest naprawdę wylosowana
System.out.print(" " + (n+1)); // n+1, bo mamy mieć od 1 do 49
}
}
}
System.exit(0);
}
}
|