• # La solution

    Posté par . En réponse au message Equivalent en Perl de Hashcode en Java. Évalué à 1.

    Merci à tous pour vos remarques et très bonnes suggestions, qui m'ont permis de trouver une solution ! Ca m'enlève une énorme épine du pied, et comme j'avais séché sur le pb un petit bout de temps, j'en suis tout content.

    Je partage donc cette solution avec vous ; elle reprend les idées de Fred, jigso et TortuXm consistant à ''remettre dans le domaine'' toute addition/soustraction qui sorte du min et du max d'un entier codé sur 64 bits.

    Comme il faut utiliser Math::BigInt, il faut bien prendre soin de passer par les méthodes idoines pour l'arithmétique et les comparaisons de ce type d'objets (cf http://search.cpan.org/~tels/Math-BigInt-1.89/lib/Math/BigIn(...) ), d'où un code un peu verbeux, et pas forcément optimisé, mais la performance est secondaire pour le problème qui m'occupe ici.
    Voici, donc :

    sub hashCode {
    my $hash = Math::BigInt->new();
    my $MAX_VALUE = Math::BigInt->new('9223372036854775808');
    my $MIN_VALUE = Math::BigInt->new('-9223372036854775807');
    foreach(split //,shift) {
    my $tmp = Math::BigInt->new();
    $tmp=$hash->copy();
    for ($i=1 ; $i<=30 ; $i++) {
    $hash->badd($tmp);
    if ($hash->bcmp($MAX_VALUE)>0) {
    $hash->bsub($MAX_VALUE);
    $hash->bsub($MAX_VALUE);
    }
    if ($hash->bcmp($MIN_VALUE)<0) {
    $hash->badd($MAX_VALUE);
    $hash->badd($MAX_VALUE);
    }
    }
    $hash->badd(ord($_));
    if ($hash->bcmp($MAX_VALUE)>0) {
    $hash->bsub($MAX_VALUE);
    $hash->bsub($MAX_VALUE);
    }
    }
    return $hash->bstr();
    }