Bug storico...

Posted by Lucio Benfante Fri, 16 Jun 2006 05:03:00 GMT

...presente nel JDK, e probabilmente nella maggior parte delle implementazioni di algoritmi con approccio “divide et impera”.

Quanti di noi non hanno mai scritto questa semplice e innocente riga di codice (con low e high di tipo int)?

int mid = (low+high)/2;

Il problema è che la somma dei due interi può risultare in un overflow…gosh…

L’implementazione corretta sarebbe qualcosa di simile a:

int mid = low + ((high-low)/2);

Provate a cercare in qualunque libro di algoritmi e vedrete che anche i grandi sbagliano. Io ho guardato in ‘The Art of Computer Programming’), e anche l’implementazione dell’algoritmo di ricerca binaria di Donald E. Knuth soffre dello stesso bug.

Per quanto riguarda il JDK, il bug si trova (almeno) nel metodo binarySearch della classe java.utils.Arrays. A me non è mai capitato, ma ve l’immaginate la sorpresa (per non dire altro) di vedervi sollevare un ArrayIndexOutOfBoundsException da un metodo di quella classe?

L’annuncio e la discussione del bug li fa lo stesso autore della classe, Josh Bloch, in questo blog.

Posted in  | Tags , , ,  | 7 comments | no trackbacks

Comments

  1. Avatar Andrea Nasato said about 5 hours later:

    Beh dai, basta che l’array su cui fai la ricerca binaria abbia meno di 2^30 elementi :)

  2. Avatar Lucio Benfante said about 6 hours later:

    Citando Knuth: “Beware of bugs in the above code; I have only proved it correct, not tried it.” :)

  3. Avatar riffraff said about 8 hours later:

    non è l’algoritmo sbagliato è il linguaggio, se la promozione tra tipi fosse implicita ( o se avessero usato BigInteger dall’inizio) il problema non sarebbe esistito.

    IIRC knuth parla dell’algoritmo in astratto (i.e. parlando di limiti considera +/- infinito ma nell’aritmetica degli interi sulle cpu che conosco questi non esistono) quindi forse non si è sbagliato.. d’altronde preferisco pensare che l’abbia fatto :)

  4. Avatar riffraff said about 8 hours later:

    no.. espresso male: è l’interazione tra algoritmo e linguaggio, poveracci gli int no hanno niente di male in se :)

  5. Avatar Lucio Benfante said 1 day later:

    In realtà, leggendolo più attentamente, l’implementazione dell’algoritmo di Knuth è corretta, ma non per il motivo espresso da riffraff.

    riffraff, hai ragione se ci limitiamo alla descrizione dell’algoritmo, con l’ipotesi che le operazioni espresse in essa, diciamo così, “in astratto” vengano poi implementate in modo che ne mantangano esattamente la semantica.

    Ma Knuth ne dà anche un’implementazione in MIX, usando il registro A per trovare l’indice intermedio:

    ENTA 0,1
    INCA 0,2
    SRB 1

    Tale registro ha la dimensione di una “word”, cioè 5 byte (da 6 bit) più il segno. Quindi va in overflow se si cerca di memorizzarvici un valore più grande di 1073741823.

    L’algoritmo però è corretto perchè ciò che viene sommato è il contenuto dei due registri I1 e I2, che sono da 2 byte più il segno, quindi la loro somma non potrà mai mandare in overflow il registro A.

  6. Avatar cig said 2769 days later:

    its a creative article.i teaches in a good way..thanks for sharing.. Regards..

  7. Avatar Nikilo said 5521 days later:

    I completely resolved my question when I read this post, thanks to the author for the very detailed description. I wrote my review on the https://cvwritingservicesuk.com/uk-careersbooster-review/, you can go in and read. Thank you very much for your attention in your time.

Trackbacks

Use the following link to trackback from your own site:
http://www.jugpadova.it/articles/trackback/923

(leave url/email »)

   Comment Markup Help Preview comment