Ciąg symboli newtona - delphi


(Mis20087) #1

Cześć

Mam przepełnienie danych, jestem początkujący. Gdzie popełniam błąd? 

Myślałem, że to będzie działać, a coś jest nie tak

 try


(kostek135) #2

Przypomina mi się jak pro dev-owie z core PHP próbowali naprawić int overflow przez porównanie z MAX_INT-em =D, priceless.


(Rolek0) #3

Silnia bardzo szybko wyczerpuje zakres inta, więc liczenie symbolu Newtona bezpośrednio z definicji nie jest zbyt dobrym pomysłem :wink:

https://pl.wikipedia.org/wiki/Symbol_Newtona#Obliczanie_symbolu_Newtona - tu masz przykładowy kod liczący w bardziej inteligentny sposób.


(Mis20087) #4

chciałem, żeby program się nie zatrzymywał z wyskakującym errorem tylko wyskakiwał komunikat tam gdzie powinien być wynik, że podałem za dużą liczbę.

Rolek0 - rzeczywiście, lepszy sposób :smiley:


(kostek135) #5

Jeśli chodzi o przepełnienie int-a, to tego nie obsłużysz porównując wynik do max int-a, to nie ma sensu - chyba że robisz core PHP wtedy ma, ponieważ tam logika nie jest wymagana. Możesz to obsłużyć przykładowymi funkcjami (Java, bo nie znam Delphi - ale jest to na tyle proste, że powinieneś przenieść to bez problemu):

public static int addWithOverflowControl(int x, int y) throws Exception {
    int r = x + y;
    
    if (((x ^ r) & (y ^ r)) < 0) {
        throw new Exception("Overflow");
    }
    
    return r;
}

 

public static int subtractWithOverflowControl(int x, int y) throws Exception {
    int r = x - y;
    
    if (((x ^ y) & (x ^ r)) < 0) {
        throw new Exception("Overflow");
    }
    
    return r;
}

 

public static int multiplyWithOverflowControl(int x, int y) throws Exception {
	int r = x * y;
	int absx = Math.abs(x);
	int absy = Math.abs(y);
	
	if (((absx | absy) >>> 15 != 0)) {
		if (((y != 0) && (r / y != x)) || (x == Integer.MIN_VALUE && y == -1)) {
			throw new Exception("Overflow");
		}
	}
	
	return r;
}