كيفية الحصول على قيمة مزدوجة عشوائية من القيم صفيف بايت عشوائية؟

StackOverflow https://stackoverflow.com/questions/403572

  •  03-07-2019
  •  | 
  •  

سؤال

وأود أن استخدام RNGCryptoServiceProvider كما بلدي مصدر من الأرقام العشوائية. كما يمكن إخراج بأنها مجموعة من القيم بايت كيف يمكنني تحويلها إلى 0-1 قيمة مزدوجة مع الحفاظ على اتساق النتائج فقط؟

هل كانت مفيدة؟

المحلول

byte[] result = new byte[8];
rng.GetBytes(result);
return (double)BitConverter.ToUInt64(result,0) / ulong.MaxValue;

نصائح أخرى

وهذه هي الطريقة التي أود أن تفعل ذلك.

private static readonly System.Security.Cryptography.RNGCryptoServiceProvider _secureRng;
public static double NextSecureDouble()
{
  var bytes = new byte[8];
  _secureRng.GetBytes(bytes);
  var v = BitConverter.ToUInt64(bytes, 0);
  // We only use the 53-bits of integer precision available in a IEEE 754 64-bit double.
  // The result is a fraction, 
  // r = (0, 9007199254740991) / 9007199254740992 where 0 <= r && r < 1.
  v &= ((1UL << 53) - 1);
  var r = (double)v / (double)(1UL << 53);
  return r;
}
<اقتباس فقرة>   

ومن قبيل الصدفة 9007199254740991 / 9007199254740992 is ~= 0.99999999999999988897769753748436 وهو ما سيعود طريقة Random.NextDouble كما انها القيمة القصوى (انظر <لأ href = "https://msdn.microsoft.com/en-us/library/system.random.nextdouble(v=vs. 110) .ASPX "يختلط =" noreferrer "> https://msdn.microsoft.com/en-us/library/system.random.nextdouble (ت = vs.110) .aspx اتصال ).

في العام، والانحراف المعياري لتوزيع الزي المستمر هو (ماكس - دقيقة) / الجذر التربيعي (12)

ومع حجم عينة من 1000 انني اتلقى موثوق ضمن هامش الخطأ 2٪.

ومع حجم عينة من 10000 انني اتلقى موثوق ضمن هامش الخطأ 1٪.

وهنا كيف لي التحقق من هذه النتائج.

[Test]
public void Randomness_SecureDoubleTest()
{
  RunTrials(1000, 0.02);
  RunTrials(10000, 0.01);
}

private static void RunTrials(int sampleSize, double errorMargin)
{
  var q = new Queue<double>();

  while (q.Count < sampleSize)
  {
    q.Enqueue(Randomness.NextSecureDouble());
  }

  for (int k = 0; k < 1000; k++)
  {
    // rotate
    q.Dequeue();
    q.Enqueue(Randomness.NextSecureDouble());

    var avg = q.Average();

    // Dividing by n−1 gives a better estimate of the population standard
    // deviation for the larger parent population than dividing by n, 
    // which gives a result which is correct for the sample only.

    var actual = Math.Sqrt(q.Sum(x => (x - avg) * (x - avg)) / (q.Count - 1));

    // see http://stats.stackexchange.com/a/1014/4576

    var expected = (q.Max() - q.Min()) / Math.Sqrt(12);

    Assert.AreEqual(expected, actual, errorMargin);
  }
}

يمكنك استخدام الأسلوب BitConverter.ToDouble (...). فإنه يأخذ في صفيف بايت وسيعود مزدوجة. ثلاث، وأساليب لمعظم أنواع بدائية أخرى، فضلا عن طريقة المقابلة للانتقال من الأوليات إلى صفيف بايت.

استخدم BitConverter لتحويل سلسلة من وحدات البايت عشوائية مزدوج:

byte[] random_bytes = new byte[8];  // BitConverter will expect an 8-byte array
new RNGCryptoServiceProvider().GetBytes(random_bytes);

double my_random_double = BitConverter.ToDouble(random_bytes, 0);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top