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();
}
# La solution
Posté par mouling . En réponse au message Equivalent en Perl de Hashcode en Java. Évalué à 1.
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();
}