« poprzedni punkt  następny punkt »

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);
  }

}


« poprzedni punkt  następny punkt »