Min ve max değerleri pozitif olduğunda neden rand () negatif bir değer dönecekti?

2 Cevap php

Ben oluşturulacak rastgele bir sayı gerektirir PHP kod basit bir parça var. Giriş her zaman pozitif olduğu halde, ancak, bazen, bir negatif çıkış verir.

İşte benim hata ayıklama kodu:

$debt = rand($this->gdp * 0.02, $this->gdp * 0.17);
echo "<p>GDP: ".$this->gdp." rand(".$this->gdp * 0.02."  , ".$this->gdp * 0.17.") = <strong>".$debt."</strong></p>";

İşte bir örnek çıktısı:

GDP: 219254674605 rand(4385093492.1 , 37273294682.85) = 75276999

GDP: 345015694865 rand(6900313897.3 , 58652668127.05) = -1636353016

GDP: 90445390920 rand(1808907818.4 , 15375716456.4) = -165604705

GDP: 3412849650 rand(68256993 , 580184440.5) = 347516196

GDP: 2939111315 rand(58782226.3 , 499648923.55) = 119181875

GDP: 26369065 rand(527381.3 , 4482741.05) = 3632416

GDP: 215838135 rand(4316762.7 , 36692482.95) = 28784811

GDP: 511763530 rand(10235270.6 , 86999800.1) = 39954394

GDP: 42416245 rand(848324.9 , 7210761.65) = 3974882

GDP: 75090235 rand(1501804.7 , 12765339.95) = 5201966

Peki neden rand() iki pozitif sayılar bir negatif geri verecekti?

Herhangi bir yardım çok takdir!

2 Cevap

Eğer argüman bir tamsayı taşması görüyoruz çünkü.

Göre rand() documentation bunu argüman olarak iki int değerleri alır. 32-bit makine üzerinde olanlar 32 bit (en azından PHP için) da vardır. Yani 2 daha argümanlar büyük geçerken 31 - 1 yine de -2 31 taşabilir ve başlayın.

Daha büyük değerler gerekiyorsa Görünüşe göre, bunu kendiniz kod gerekecek. Bu dağıtım eğriltir bu yana sadece iki 32-bit numaraları bir 64-bit sayı üretirken istendiği gibi çalışır, sadece maksimum değere sahip bir modül işlemi yapamaz. 0 ve belli bir üst sınır arasında eşit dağıtılmış rasgele tamsayı oluşturmak için nasıl iyi bir uygulama için, java.util.Random.nextInt(int) bir göz atın ve 64 bit tamsayılar için buna göre uyarlamak.

mt_rand(), genellikle rastgele sayılar için güzel bir seçim, bunun yerine bir fakir LCG MT19937 kullanır, çünkü, burada da yardım etmez argümanları gibi int de var iken.


Eğer düşünebilirsiniz başka bir seçenek if you don't require every possible value to be picked eventually:

  • Arayarak 0 ile 1 arasında rastgele bir kayan nokta değeri üretmek

    $rnd = mt_rand() / (double)mt_getrandmax()
    
  • İhtiyacınız numaraları aralığını belirleyin:

    $min = $this->gdp * 0.02;
    $max = $this->gdp * 0.17;
    $range = $max - $min;
    
  • Daha önce elde edilen rastgele kayan nokta değeri ile çarpın ve minimum ekleyin:

    $value = $min + $range * $rnd
    
  • Şimdi seçtiğiniz sınırları arasında rastgele bir değer var. Eğer bit daha çok sayıda üzerinde rastgele 32 bit germe gibi komşu rasgele sayılar arasındaki ayrık adımlar olmakla beraber yaklaşık olarak eşit dağıtılmış oluyor. Bu sizin için sorun yok, olsa da, devam edin.

Rand argüman olarak alır ve döner, integers. (PHP) tamsayılar genellikle 2 ** 32 üzerinde bir menzile sahip.

Sizin çift argümanlar neden, bu daha büyük bir integer overflow onlar tamsayılar dönüştürülür zaman.