Bonjour,
Dans certaines circonstances particulières j'ai décelé un bug (?) de la fonction Random() de Delphi 7 et Delphi 2010.
Je vous donne ci-dessous un bout de code qui met ce bug en évidence.
J'aimerais savoir si ce bug a déjà été signalé et s'il existe aussi sur les dernières versions de Delphi, et pourquoi pas pour d'autres langages.
Existent-il des solutions, selon vous ?
Pour cela, ce serait sympa que ceux qui disposent d'autres versions essaient de le reproduire et nous retournent l'information.
LE BUG :
Dans certains cas, le générateur de nombres pseudo-aléatoires semble "éviter" certaines valeurs.
Cela semble se produire dans des suites d'appels de Random régulières et bien particulières.
CE QUE FAIT LE BENCHMARK A TESTER :
Le test consiste à "tirer" aléatoirement sur la surface d'un Bitmap avec deux méthodes différentes.
La première méthode est classique et consiste à tirer un pixel aléatoire sur toute la surface.
La deuxième méthode est destinée à réduire la discrépance des nombres pseudo-aléatoire (la dicrépance mesure de combien un ensemble de points s'écarte d'une distribution spaciale uniforme). Elle consiste à diviser la surface du Bitmap en plus petits carrés réguliers de 4x4 pixels et a "tirer" au hasard dans chaque petit carré. C'est dans ce cas que le bug se produit. En effet, après un nombre important de "tirs" (environ 200 salves), les 2 images devraient devenir complétement noires. Or ce n'est pas le cas pour l'une d'elles.
Bizarrement, ce bug ne se produit que pour certaines dimensions de Bitmap (256x256 et 512x512 par exemple, mais pas pour 128x128 ou 240x240 pixels. Il se produit aussi pour des petits carrés de 2x2 ou 8x8 pixels).
Dans cet exemple, on arrive à éviter ce bug en effectuant un appel bidon à Random() de temps en temps, mais dans d'autres cas, comment savoir si le bug est présent ou non ?
Pour Info, cette technique de faible discrépance alliée à la méthode de Monte Carlo est utilisée dans certains calculs de produits financiers exotique (titrisation) comme ceux à l'origine de la crise des subprimes survenue en 2007.
Mais qu'on se rassure, l'origine de la crise n'est pas là !
Le test est très facile a réaliser. 2 TImages AutoSize à true, 1 TButton et un TEdit sur une fiche :
Merci de m'avoir lu et à ceux qui feront le test pour retour d'informations.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 var gShootsNb : Integer; procedure TForm1.FormCreate(Sender: TObject); begin Randomize; Image1.Picture.Bitmap.Height := 256; Image1.Picture.Bitmap.Width := 256; Image2.Picture.Bitmap.Height := 256; Image2.Picture.Bitmap.Width := 256; end; {Génère une salve de 4096 tirs.} procedure TForm1.bButton1Click(Sender: TObject); var i,j,X,Y : Integer; begin Inc(gShootsNb); Edit1.Text := IntToStr(gShootsNb); for i := 0 to 63 do begin for j := 0 to 63 do begin {Suite quasi-aléatoire pour Image1} X := (i*4) + Random(4); Y := (j*4) + Random(4); //if X=0 then Random(Y); // DE-SLACHER POUR FIXER LE BUG. if Image1.Picture.Bitmap.Canvas.Pixels[X,Y]=clWhite then Image1.Picture.Bitmap.Canvas.Pixels[X,Y]:=clBlack; {Suite pseudo-aléatoire pour Image2} X := random(256); Y := random(256); if Image2.Picture.Bitmap.Canvas.Pixels[X,Y]=clWhite then Image2.Picture.Bitmap.Canvas.Pixels[X,Y]:=clBlack; end; end; end;
Partager