Bug randomrange

4/5 (20 avis)

Vue 6 813 fois - Téléchargée 191 fois

Description

Suite à l'étude du code proposé par florenth (http://www.delphifr.com/code.aspx?ID=34509) je me suis aperçu d'une erreur dans le code de la fonction RandomRange de l'unité Math.pas. En effet si l'on demande par exemple des nombres aléatoires de 3 à 8, la fonction renvoie des nombres de 3 à 7 !!

Voici le correctif à apporter.

Source / Exemple :


// ----- Code modifié ----- //
function RandomRange(const AFrom, ATo: Integer): Integer;
begin
  if AFrom > ATo then
    Result := Random(AFrom - ATo + 1 ) + ATo
  else
    Result := Random(ATo - AFrom + 1 ) + AFrom;
end;

Conclusion :


Quelques explications, sur la modification de la fonction originelle :

// ----- Code originel ----- //
function RandomRange(const AFrom, ATo: Integer): Integer;
begin
if AFrom > ATo then
Result := Random(AFrom - ATo) + ATo
else
Result := Random(ATo - AFrom) + AFrom;
end;

Supposons que Afrom=2 et ATo=3, dans ce cas, on aura Random(3-2)+2 soit Random(1)+2
0 <= Random(X) < X
0 <= Random(1) < 1
2 <= Random(1)+2 < 3, la fonction RandomRange ne renverra que des 2 !!!!

Supposons que Afrom=1 et ATo=5, dans ce cas, on aura Random(5-1)+1 soit Random(4)+1
0 <= Random(X) < X
0 <= Random(4) < 4
1 <= Random(4)+1 < 5, la fonction RandomRange renverra des nombres compris entre 1 et 4 !!!! et non 1 et 5

Pour utiliser le correctif, soit vous recompilez l'unité Math.pas en modifiant la source (pour ceux qu'ils l'ont), soit vous intégrez ce code dans une autre unité, par exemple CorrectifMath.pas (fichier joint)
L'appel de la fonction se fera en incluant l'unité dans la clause uses, puis en spécifiant au compilateur l'unité à utiliser :

RandomRange(1,5); // Appel de la fonction originelle
Math.RandomRange(1,5)); // Appel de la fonction originelle
CorrectifMath.RandomRange(1,5)); // Appel de la fonction corrigée

Cordialement.

Codes Sources

A voir également

Ajouter un commentaire Commentaires
cirec
Messages postés
3832
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
17 février 2022
48
7 déc. 2005 à 00:14
You welcome

ça nous arrive a tous et si c'est pas le cas ça arrivera

@+
Cirec
WhiteHippo
Messages postés
1154
Date d'inscription
samedi 14 août 2004
Statut
Membre
Dernière intervention
5 avril 2012
2
7 déc. 2005 à 00:06
Merci Cirec pour la note et pour avoir corriger ma grossière erreur (Oups !!) C'est ça de vouloir poster trop rapidement. Pourtant j'avais bien relu, 2 fois au moins comme le précise la nétiquette, mais pour les fautes d'orthographes pas pour celle du code (fait au feeling j'avoue) ;D

Cordialement.
cirec
Messages postés
3832
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
17 février 2022
48
6 déc. 2005 à 23:26
Ps: je met une note de dix non pas parce que le code est extraordinaire non mais parce que ça fait longtemps que j'avais remarqué cela... mais bon j'ai trouvé ça normal et j'ai pas cherché plus loin. #^_^#

@+
Cirec
cirec
Messages postés
3832
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
17 février 2022
48
6 déc. 2005 à 23:20
Effectivement cette version là est buggée (tu compiles même pas) ^_^:
randomrange( Low(TMonChoix), High(TMonChoix) )

Je pense que celle-ci fonctionnera un peut mieux: randomrange( Integer(Low(TMonChoix)),
Integer(High(TMonChoix)) );

sans pour autant donner le bon résultat il manquera toujours "mcOuEncoreCela" je vous l'accorde.

@+
Cirec
WhiteHippo
Messages postés
1154
Date d'inscription
samedi 14 août 2004
Statut
Membre
Dernière intervention
5 avril 2012
2
6 déc. 2005 à 19:28
Moi Mauricio, ce qui me chagrine, ce le fait de persister dans une voie toute en sachant qu'elle est erronée. Une volonté de comptabilité, soit mais le problème c'est que de nombreuses sources qui utilisent cette fonction, ne fonctionne certainement pas correctement.
Un autre exemple d'utilisation buggée :

type
TMonChoix = ( mcCeci, mcCela, mcOuCeci, mcOuCela, mcOuEncoreCeci, mcOuEncoreCela ) ;

Un appel de TMonChoix( randomrange( Low(TMonChoix), High(TMonChoix) ) ) ne fournira jamais mcOuEncoreCela.

Volonté de compatibilité soit mais alors volonté de compatibilité des bugs !!! ;P

Quand à la modification du nom, pas vraiment, enfin pas tout à fait. Je verrais plutot une modification du code pour cette fonction, plus une nouvelle fonction RandomRangeExclusive qui reprendrait l'ancien code. Cela serait, je pense, beaucoup plus cohérent.

N.B. Je ne pense pas que la modification de ce code entraine de grandes modifications, mais il permettra simplement à ses utilisateurs d'avoir TOUTES les valeurs normallement prévues!!

Cordialement.
Afficher les 20 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.