Przeskocz do treści

Delta mi!

Czy math?

Jakub Radoszewski

o artykule ...

  • Publikacja w Delcie: luty 2012
  • Publikacja elektroniczna: 01-02-2012

Poszukiwanie pierwiastków wielomianu jest jednym z podstawowych zagadnień rozważanych we wszystkich naukach ścisłych. W tym artykule zajmiemy się czymś znacznie prostszym: sprawdzaniem, czy dana liczba jest pierwiastkiem zadanego wielomianu.

Mając dany wielomian math  i konkretną wartość parametru math chcemy więc sprawdzić, czy math  Można by spytać, czy nie wystarczy w tym celu podstawić wartość math i na tym skończyć? Rzeczywiście, jeśli mamy do czynienia z „nieskomplikowanym” wielomianem (cokolwiek by to miało znaczyć) i „sensownym” parametrem math to problem jest trywialny. Może się jednak okazać, że nasze dane nie są „nieskomplikowane i sensowne”, ale za to możemy wesprzeć się domowym komputerem...

Przede wszystkim należy sprecyzować, jakimi liczbami zamierzamy się zajmować. Aha, a więc to tutaj tkwi haczyk! Podejrzliwy Czytelnik zapewne domyśla się już, że za moment wkroczymy w mroczny świat komputerowych reprezentacji liczb rzeczywistych, z przybliżeniami, cechami, mantysami i wszędobylskimi epsilonami. Faktycznie, komputerowe sprawdzenie równości math  w liczbach rzeczywistych nastręcza pewnych trudności i jest istotnym zagadnieniem w dziedzinie metod numerycznych. My jednak nie będziemy się w to tutaj wgłębiać i założymy, że mamy do czynienia wyłącznie z liczbami całkowitymi. Czy w takim razie problem zawiera w sobie jeszcze jakąś trudność? Owszem.

Otóż nieprzyjemne jest to, że przy obliczaniu math  szybko zaczynamy mieć do czynienia z bardzo dużymi liczbami. I to nawet wtedy, gdy współczynniki math są niewielkie, co dla informatyka znaczy, że co do wartości bezwzględnej nie przekraczają dwóch miliardów (orientacyjne ograniczenie standardowego typu całkowitego 32-bitowego ze znakiem; faktycznie jest to math czyli trochę więcej). Rzeczywiście, bez trudu widzimy, że jednym z pierwiastków wielomianu:

display-math

jest math ale jeśli chcielibyśmy to sprawdzić, wykonując proste podstawienie, musielibyśmy operować na liczbach zawierających 1000 cyfr. Nawet osoba niezaznajomiona z komputerem łatwo zauważy, że obliczenia na takich długaśnych liczbach muszą być w jakimś sensie trudniejsze. Tak jest w istocie: wykonywanie operacji na dużych liczbach jest powolne, a do tego bywa wyjątkowo niewygodne, jeśli akurat natrafimy na system czy język programowania, który dostarcza implementacje działań jedynie na wbudowanych typach całkowitych, co zazwyczaj oznacza liczby 64-bitowe (ze znakiem), czyli mniejsze co do wartości bezwzględnej niż math No dobrze, ale my chcemy tylko sprawdzić, czy math  a niekoniecznie od razu obliczyć dokładną wartość math – to przecież musi być prostsze! I rzeczywiście: poniżej opisujemy krótką i elegancką metodę rozwiązującą ten problem.

Załóżmy, że math – z przypadkiem math łatwo sobie poradzić, sprawdzając, czy math Chcemy stwierdzić, czy:

display-math

równoważnie czy:

display-math

Lewa strona jest podzielna przez math a zatem prawa też musi dzielić się przez math Otrzymujemy pierwszy warunek konieczny na to, żeby math było pierwiastkiem math :

display-math(1)

Jeśli on zachodzi, możemy całą równość podzielić przez math otrzymując:

display-math

Ta sytuacja jest podobna do poprzedniej. Przerzucamy math na drugą stronę:

display-math

i otrzymujemy drugi warunek konieczny:

display-math(2)

Następnie znów dzielimy obie strony równości przez math i kontynuujemy to postępowanie, aż po lewej stronie pozostanie samo math Po drodze otrzymamy kolejne warunki konieczne na to, żeby math było pierwiastkiem wielomianu math  na przykład trzeci z nich będzie postaci:

display-math(3)

Na końcu zaś wystarczy sprawdzić, czy:

display-math(4)

W ten sposób uzyskujemy następujący pseudokod, w którym sprawdzamy kolejno warunki (1), (2), (3) itd., a na końcu (4).

display-math

Zauważmy, że wartość zmiennej math  nigdy nie przekroczy sumy wartości bezwzględnych liczb math więc nie będziemy mieć do czynienia z żadnymi dużymi liczbami. Czyli pełny sukces!

Na zakończenie warto dodać, że podany problem można także rozwiązać za pomocą tak zwanego schematu Hornera, w którym wykorzystujemy następujące przedstawienie:

display-math

Wystarczy mianowicie próbować obliczyć math  zgodnie z tym schematem, od lewej do prawej – na przemian mnożymy przez math i dodajemy math – przy czym obliczenia przerywamy, jeśli aktualna wartość staje się zbyt duża. Wiemy wówczas, że na pewno wynikiem nie będzie zero. A to, jaka jest ta graniczna wartość, przy której możemy od razu udzielić odpowiedzi negatywnej, pozostawiamy do rozstrzygnięcia Czytelnikowi.