我想使用C#生成从-1到1的均匀分布的随机数,在数学符号中是U(-1,1)。预期结果应该是实数。
答案 0 :(得分:7)
User Random.NextDouble()并将结果乘以2然后减去1.
代码:
var rand = new Random();
var value = rand.NextDouble() * 2 - 1;
答案 1 :(得分:0)
作为扩展方法:
public static double NextDoubleBetween(this Random r, double lower, double upper)
{
return r.NextDouble() * Math.Abs(upper - lower) + lower;
}
使用:
Random r = new Random();
Console.WriteLine(r.NextDoubleBetween(-1, 1));
答案 2 :(得分:0)
目前,只有密码学的特殊情况才能以强有力的方式(有理论证据)保证随机数的真正一致性。
Random
类提供了一些非均匀甚至可预测的行为,而强大(且昂贵)的实现在不可预测性方面更可靠。
您可以在此处找到该课程:RandomNumberGenerator crypto service provider implementation on MSDN
有关RNG的快速信息:RNG on DotNet Perls
注意那里(在DotNet Perls上)在Random和RandomNumberGenerator之间创建数字的成本:2796 ns而不是9 ns ......这可以告诉你这个数字是多少以及需要多少注意力采取这种非常强有力的实施。
要使一个介于-1和1之间的数字,你必须做一些腿部工作,因为你只能从 RNG 获得原始字节,但这应该可以很好地帮助你:
您应该使用 RNG 中的字节填充数组,然后使用BitConverter.ToDouble()
保留尽可能多的熵:
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
byte[] buffer64bit = new byte[4];
rng.GetBytes(buffer64bit);
double value = BitConverter.ToDouble(buffer64bit, 0);
}
您现在必须将其限制在-1到+1之间,因为value
的范围是double.MinValue
到double.MaxValue
。你可以通过使用模2然后减去1:
value = (value % 2) - 1;
这将是从-1到+1的随机双倍,具有与C#中当前可能的一致性。要超越你需要一个专门的实现,它连接到 RNG (这与用于极其强大的加密实现的热传感器的硬件生成器一起使用)。
答案 3 :(得分:0)
pid答案有一个小错误。分配的缓冲区是32位而不是64位。因此,请更改:
byte[] buffer64bit = new byte[4];
收件人:
byte[] buffer64bit = new byte[8];