svn commit: r300956 - head/lib/libc/stdlib

Bruce Evans brde at optusnet.com.au
Tue May 31 14:17:57 UTC 2016


On Tue, 31 May 2016, Andrey Chernov wrote:

> On 31.05.2016 12:58, Bruce Evans wrote:
>> On Tue, 31 May 2016, Andrey Chernov wrote:
> ...
>>> You can download SPRNG library implementing all of them here:
>>> http://www.sprng.org/RNG/
>>> For me it is overcomplicated.
>>
>> The general case is certainly too complicated.  It would let the user
>> specify all the parameters for the LCG and generate optimal code for
>> the choice on the fly.  Maybe also change the parameters with the seed.
>> But even most implementors don't know how to choose the parameters.
>> That's just for the not so good LCG family of RNGs.
>
> All mentioned PRNGs with exact parameters (info.h) can be found in the
> subdirs under SRC, f.e. lcg64 or pmlcfg. They are still looks
> complicated and use GMP Bignum library for calculations.

Our rand should use just 1, and it is dangerous to change RAND_MAX again,
but can we even change the sequences?  Something might depend on 
reproducing the old sequences.

>>> For fixups, see full
>>> explanation in the comment of stdlib/div.c
>>
>> That was what I was complaining about.  div.c is for C90 (misspelled
>> "ANSI").  div.c hasn't caught up with C99.  C99 broke this by changing
>> ...
>>
>> In C90, div() is specified as giving "reliable" division, and that is
>> what the fixups implement.  This now wastes time to change nothing.
>> If the hardware does correct rounding, then the compiler already
>> had to do the fixup and id should have produced good MD code for this.
>> The C code then adds not so good MI code.
>
> It seems POSIX says nothing about any fixup and negative results:
> "These functions shall compute the quotient and remainder of the
> division of the numerator numer by the denominator denom. If the
> division is inexact, the resulting quotient is the long integer (for the
> ldiv( ) function) or long long integer (for the lldiv( ) function) of
> lesser magnitude that is the nearest to the algebraic quotient. If the
> result cannot be represented, the behavior is undefined; otherwise, quot
> * denom+rem shall equal numer."

This uses the same not so good wording as C90.  "algebraic" means
"in the field of ordinary rational numbers", not in a general algebraic
object.  Then we use the ordering property of the rationals, so we're
closer to analysis than algebra.

POSIX doesn't define the division operator, and the difference is only
there, except for bugs in the wording.  In C90, the rounding can go
either way so the fixup is needed, but in C99 and C11 the division
operator is intended to be specified to do the same rounding as div()
used to be specified to do, but with the unimproved wording "the result
[of division] is the algebraic quotient with any fractional part
discarded".  C99 and C11 remove the special wording for div().  This
removes all ordering requirements from the standard (1 was moved to
a footnote), so C has "unreliable" division again, depending on the
unspecified choice of sign for the fractional part.

> Does it mean that this fixup should be removed?

Just ifdef it for < C99.  This corresponds to removing the special wording
in >= C99.

Bruce


More information about the svn-src-all mailing list