Poprawność wyników , dużych liczbach zmiennoprzecinkowych (zadanie z Polski Spoj)

0

Dobry wieczór, zaczynam przygodę z javą i rozwiązuje zadania z Polskiego Spoja, zadanie to : ETI06F1 - Pole pewnego koła. Program który napisałem wywala mi błędne wyniki jeśli chodzi o duże liczby (np: podając bna wejsciu: 1000 , 1500). Zastosowałęm zaokrąglanie ale , to nic nie daje , poniewaz to tylko mi zaokrągla do 2 miejsc po przecinku. Doczytałem się iż za poprawne wyniki moze odpowiadać funkcja BigDecimlal , czy dobrze myślę ??? Jeśli tak to w jaki sposób ją zastosować w programie?

Treść zadania:


Wyznacz pole koła, którego okrąg jest przecięciem dwóch identycznych sfer o promieniu r. Odległość pomiędzy środkami sfer wynosi d. Wartości r oraz d podane na wejściu są liczbami zmiennoprzecinkowymi. Można założyć, że 1 <= d < 2 * r <= 200

Wejście: 
Na wejściu podane są dwie liczby zmiennoprzecinkowe r d oddzielone spacją, oznaczające odpowiednio promień sfery i odległość między środkami sfer.

Wyjście
Należy wypisać pojedynczą liczbę zmiennoprzecinkową S oznaczającą pole koła. Dopuszczalny błąd wyniku wynosi 0.01.

Uwaga. W roli separatora dziesiętnego należy używać kropki (nie: przecinka). Można przyjąć, że stosunek obwodu koła do jego średnicy wynosi 3.141592654.
 
 
package lekcja2;

import java.util.Scanner;

public class polePewnegoKola {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		double d,r,polowa,h,pole,pole2;
		Scanner skan = new Scanner(System.in);
		
			System.out.println("Podaj odleglosc pomiedzy srodkami sfer: ");
			d = skan.nextInt();
		
			System.out.println("Podaj promien sfer: ");
			r = skan.nextInt();
		
			polowa=d/2;

			h= (Math.pow(r, 2)- Math.pow(polowa, 2) );
			h=(Math.sqrt(h) );

			

	
			pole=3.141592654*Math.pow(h, 2);
			pole = pole * 100;
			pole = Math.round(pole);
			pole = pole / 100;
			
			System.out.println("Pole:\n" + pole);
    
	}

}


0

Dobrze myślisz, z tym wyjątkiem że BigDecimal to obiekt który przechowuje liczbę stałoprzecinkową o prawie dowolnej dokładności (czyli nie jest to funkcja). Jako że jest to zwykły obiekt, musisz użyć metod, ponieważ nie ma tutaj przeciążonych operatorów. Zwróć też uwagę że jest to obiekt Immutable (niezmienny), czyli wykonując operację np. dodawania, musisz brać pod uwagę rezultat zwrócony z metody, ponieważ oryginalny obiekt nie zostanie zmieniony.

  d = skan.nextBigDecimal();
  r = skan.nextBigDecimal();
  BigDecimal polowa = d.divide(new BigDecimal(2), RoundingMode.HALF_DOWN);
  BigDecimal h = r.pow(2).subtract(polowa.pow(2));
  ...

Zauważ że BigDecimal nie pozwoli Ci na utratę żadnych informacji. Dlatego przy divide który może uciąć jakaś część danych, musisz podać sposób zaokrąglania. Jeżeli go nie podasz, a wywołasz operację która spowoduje utratę danych (np. 1/3) dostaniesz wyjątek.

0

Dziękuję, ale następne w kolei działanie to pierwiastek z h.... niewiem jak w tej metodzie BidDecimal zadeklarowac pierwiastek.

Czyli mając juz Bigdecimal h.... chciałbym go pierwiastkować (czyli co , utworzyć zmienną Bigdecimal, np h1 tak?):

 BigDecimal h1 = sqrt(h);

i tu mi wywala błąd pod sqrt...

1 użytkowników online, w tym zalogowanych: 0, gości: 1