Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么在尝试使用相同的参数运行相同的方法时会出现溢出异常?_C# - Fatal编程技术网

C# 为什么在尝试使用相同的参数运行相同的方法时会出现溢出异常?

C# 为什么在尝试使用相同的参数运行相同的方法时会出现溢出异常?,c#,C#,正在考虑创建一个支持uint、long和ulong的随机数生成器。我开始做随机的uint生成器,但是我一直在做一个最小,最大的生成器 这就是我所拥有的 public class Rand : System.Random public uint UInt32(uint min, uint max) { byte[] array = new byte[4]; base.NextBytes(array); uint result = BitConverter.ToUInt

正在考虑创建一个支持uint、long和ulong的随机数生成器。我开始做随机的uint生成器,但是我一直在做一个最小,最大的生成器

这就是我所拥有的

public class Rand : System.Random

public uint UInt32(uint min, uint max)
{
    byte[] array = new byte[4];

    base.NextBytes(array);

    uint result = BitConverter.ToUInt32(array, 0);

    if (result < min | result > max)
    {
        UInt32(min, max); //here i get a StackOverflowException
    }
    return result;
}

为什么在尝试使用相同参数运行相同方法时会出现StackOverflowException?

您的程序退出递归调用的能力取决于间隔的长度[min..max]。间隔越小,命中StackOverflowException的概率越高

由于生成的是4字节整数,因此有232个可能的值。假设随机值均匀分布,命中最小值和最大值之间间隔的概率等于最大值最小值*2-32。继续递归调用的概率为1-max-min*2-32。如果希望递归调用有机会在合理的调用次数内结束,那么与232相比,min和max之间的间隔应该相当大


通过将递归代码转换为迭代代码,您可以避免堆栈溢出,但代价是代码速度较慢。您的递归实现也是错误的,因为它会丢失递归调用的结果,但无论如何都不值得修复。

您是否尝试过调试它,以一步一步地查看它实际在做什么,观察变量?您可能会回答自己的问题。基本上,您永远不会从递归函数返回。如果resultmax是正确的还是应该是| |?您会生成随机数,如果它与条件min max range不匹配,则再次调用同一个函数。但随机数可能会多次不符合此条件,而堆栈大小不是无限的,因此递归调用占用所有堆栈的频率通常取决于最小值和最大值。这不是你应该在一个范围内生成随机数的方式。是什么让迭代方法假设你只是意味着一个稍慢的循环?或者你的意思是它通常很慢,而不是比递归版本慢,如果它没有溢出的话?除了你的最后一句话,一切都很好-你不能通过授权给Randomint,int轻松实现Randommin,max,更不用说ulong了。特别是对于ulong,如果您想要一个合适的分布,即使是Sample也不行,因为它在内部只缩放一个int。当然有。@Chris它不会使它变慢,它会使它在绝对值上变慢。递归代码将与迭代代码一样快。事实上,它可以为尾部调用优化而重新构造。@JeroenMostert您可以在未加密的上下文中对uint执行Randomint、int和cast result。因为int和uint具有相同的大小-这将很好地工作负int将导致大的正uint。对乌龙来说,情况确实不同。@Demiz:算出你的射程大小如何。四舍五入至最接近的2次方。生成一个介于0和2的幂之间的随机数。比特屏蔽。丢弃那些现在有50%几率超出范围的物品。将最小值添加到数字中,使其回到实际范围。也许有更好的方法可以做到这一点,但这至少可以保证使用相对简单的算法实现一致性。