⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rand.20000223.html

📁 this is a mirrored site c-faq. thought might need offline
💻 HTML
字号:
<html><!-- Mirrored from c-faq.com/lib/rand.20000223.html by HTTrack Website Copier/3.x [XR&CO'2008], Sat, 14 Mar 2009 08:03:00 GMT --><head><title></title></head><body>[This is a reply from meto a correspondent of minewho had asked about some of the expressionsin the answer to <a href="randrange.html">question 13.16</a> in the FAQ list.I have edited the text slightly for this web page.]<p>Date: Wed, 23 Feb 2000 07:08:14 -0800 (PST)<br>Message-Id: &lt;200002231508.HAA07282@mail.eskimo.com&gt;<br>Subject: Re: C FAQ error?<p>The water is surprisingly deep here.  I was initially ratheralarmed by your note, because after rummaging around for some ofmy old random number testbeds and dusting them off, I found thatthe expression<pre>	rand() / (RAND_MAX/N + 1)</pre>from the FAQ list doesn't behave as well as I expected it to.When I then attempted to rederive the appropriate expression,my first attempt led to<pre>	rand() / ((RAND_MAX + 1) / N)</pre>which is exactly what you suggested.  But it turns out that thelatter expression doesn't work in the general case.  Supposethat <TT>RAND_MAX</TT> is 21 and <TT>N</TT> is 10.  (As it happens, this was thefirst example I tried.)  So <TT>((RAND_MAX&nbsp;+&nbsp;1)&nbsp;/&nbsp;N)</TT> is then 2, andwhen <TT>rand()</TT> returns 20 or 21, the value of the expression is 10,which is not in [0,&nbsp;<TT>N</TT>).<p>I want to study your... derivation some more,because I think it's basically sound, for the ``|<TT>RAND_MAX</TT>+1| is aprecise multiple of |<TT>N</TT>|'' case.  I suspect that the flaw, however,is in your assumption that if <TT>RAND_MAX</TT>+1 is not a multiple of <TT>N</TT>,the same logic applies.  You have to make sure that the resultfalls the right way when the intermediate quotient discards anonzero remainder, and for this expression, it doesn't.<p>Unfortunately, I don't immediately remember how I originallyderived the expression<pre>	rand() / (RAND_MAX/N + 1)</pre>I share your unease about its dissimilarity to the (much cleaner)floating-point version<pre>	rand() / (RAND_MAX + 1.0) * N</pre>I do remember testing the expressions in the FAQ list quitethoroughly, and I've found <a href="rand.931117.html">an article</a> I posted long ago whichdiscusses them in some detail, and which suggests that I putquite a bit of time into that initial derivation.  (It alsosuggests that I wasn't perfectly happy with the expression then,either.)  That article, as I read it now, is nowhere as clearas I'd like, and I was about to be at a loss to explain how<pre>	rand() / (RAND_MAX/N + 1)</pre>works at all, until I discovered that the expression isessentially the same one I explain in the answer to exercise 8at <a href="http://www.eskimo.com/~scs/cclass/asgn.beg/PS3a.html">http://www.eskimo.com/~scs/cclass/asgn.beg/PS3a.html</a>, whichis worth reading.  (I must confess, though, that I can't imaginewhat I was thinking when I started throwing that much detailaround in the third week of an allegedly beginning programmingclass.)  But going back to the <TT>RAND_MAX</TT>=21, <TT>N</TT>=10 case, it turnsout that dividing <TT>rand()</TT> by 3, such that we never emit 8 or 9 atall, is about the best we can do; what we're seeing is one of theways that any of these expressions begins to fail when <TT>RAND_MAX</TT>+1is neither a multiple of nor much greater than <TT>N</TT>.<p>For my own reference, here's another way of deriving theexpression <TT>rand()&nbsp;/&nbsp;((RAND_MAX&nbsp;+&nbsp;1)&nbsp;/&nbsp;N)</TT>, even though thatexpression doesn't work.  We want to divide <TT>rand</TT>'s output bysome integer y such that the answer is always in the range0 &lt;= <TT>rand()</TT>/y &lt; <TT>N</TT>.  Now when rand returns <TT>RAND_MAX</TT>, the result<TT>RAND_MAX</TT>/y should be just barely less than <TT>N</TT>; one way ofachieving this would be if it were the case that (<TT>RAND_MAX</TT>+1)/ydid equal <TT>N</TT>.  So if we set (<TT>RAND_MAX</TT>+1)/y = <TT>N</TT>, we can easilysolve for y = (<TT>RAND_MAX</TT>+1)/<TT>N</TT>.<p>But wait!  If we want <TT>RAND_MAX</TT>/y to be just barely less than <TT>N</TT>,the other way to achieve it is to subtract 1 in the denominator.So if <TT>RAND_MAX</TT>/(y-1) = <TT>N</TT>, we have y = <TT>RAND_MAX</TT>/<TT>N</TT> + 1, and thismust be where the expression in the FAQ list comes from, afterall.</body><!-- Mirrored from c-faq.com/lib/rand.20000223.html by HTTrack Website Copier/3.x [XR&CO'2008], Sat, 14 Mar 2009 08:03:00 GMT --></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -