如何在C#中生成一致随机数U(-1,1)?

如何在C#中生成一致随机数U(-1,1)?,c#,C#,我想用C#生成一个从-1到1的均匀分布随机数,在数学符号中是U(-1,1)。预期结果应该是一个实数 User Random.NextDouble()并将结果乘以2,然后减去1 守则: var rand = new Random(); var value = rand.NextDouble() * 2 - 1; 作为一种扩展方法: public static double NextDoubleBetween(this Random r, double lower, double upper) {

我想用C#生成一个从-1到1的均匀分布随机数,在数学符号中是U(-1,1)。预期结果应该是一个实数

User Random.NextDouble()并将结果乘以2,然后减去1

守则:

var rand = new Random();
var value = rand.NextDouble() * 2 - 1;

作为一种扩展方法:

public static double NextDoubleBetween(this Random r, double lower, double upper)
{
    return r.NextDouble() * Math.Abs(upper - lower) + lower;
}
使用:


目前,只有在密码学的特殊情况下,才能以强有力的方式(通过理论证明)保证随机数的真正一致性

Random
类表现出一些不一致甚至可预测的行为,而强大(且昂贵)的实现在不可预测性方面要可靠得多

您可以在此处找到该类:

有关RNG的快速信息:

请注意(在DotNet Perls上)在Random和RandomNumberGenerator之间创建数字的成本:2796纳秒对9纳秒。。。这会告诉您这是多么昂贵,以及对于这个非常强大的实现采取了多大的谨慎

要使数字介于-1和1之间,您必须做一些腿部工作,因为您只能从RNG获取原始字节,但这应该可以很好地帮助您:

您应该使用RNG中的字节填充数组,然后使用
位转换器.ToDouble()
尽可能保留熵:

using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
    byte[] buffer64bit = new byte[4];

    rng.GetBytes(buffer64bit);
    double value = BitConverter.ToDouble(buffer64bit, 0);
}
您现在必须将其从-1限制到+1,因为
值的范围是
double.MinValue
double.MaxValue
。可以通过使用模2,然后减去1来实现这一点:

value = (value % 2) - 1;

这将是一个从-1到+1的随机双精度,具有与当前C#中尽可能多的一致性。要超越这一点,您需要一个专门的实现,该实现与RNG挂钩(这与使用热敏传感器的硬件生成器一起使用,用于极强的加密实现)。

pid answer有一个小错误。分配的缓冲区是32位而不是64位。因此,改变:

byte[] buffer64bit = new byte[4];
致:


更具体地定义“数字”。预期结果是整数还是实数?我猜它们是在标量之后,所以-1.0->1.0是的,这是有意义的,但有些人可能也想随机获得-1、0或1。我不熟悉
U(-1,1)
符号,不过…@davbryn您可以搜索“何时使用
var
以及何时使用
realtype
”。我看这里没有问题。@davbryn写得更少了。。。在这里它不是很有用,但是想象一下List.GetEnumerator()返回的类型,例如:)我不擅长数学表示法,但是排除-1很容易,加上1并保持一致性要困难一些。@davbryn你想说什么?这个话题被讨论了数百万次,C#community(我希望)知道何时使用它。如果你真的对它感兴趣,可以去相关的论坛。@L.B完全明白这一点:评论部分不是用来提问的,而是用来讨论的。你突然告诉我要为一个我没有问你的问题寻找答案;顺便说一句,如果以前有人问过它一百万次,那么许多人的共识肯定是这是一个缺陷?
byte[] buffer64bit = new byte[4];
byte[] buffer64bit = new byte[8];