Different results for uniform random number generation between D and Boost
Nick Sabalausky
SeeWebsiteToContactMe at semitwist.com
Mon Jul 30 18:00:23 PDT 2012
On Tue, 31 Jul 2012 00:33:43 +0100
Joseph Rushton Wakeling <joseph.wakeling at webdrake.net> wrote:
> Hello all,
>
> A little curiosity I noticed when comparing fine-detailed results
> from simulations where I had code in both C++ and D.
>
> Here's a little program that prints out the first 10 results of the
> Mersenne Twister RNG, and then uses the same sequence to generate 10
> uniformly-distributed numbers in [0, 1).
>
> ////////////////////////////////////////////////////////////////////////////
> import std.random, std.range, std.stdio;
>
> void main()
> {
> auto rng = Random(12345);
>
> foreach(x; takeExactly(rng, 10))
> writeln(x);
>
> writeln();
> writeln("Min: ", rng.min);
> writeln("Max: ", rng.max);
> writeln();
>
> rng.seed(12345);
>
> foreach(i; 0..1000)
> writefln("%.64f", uniform!("[)", double, double)(0.0,
> 1.0, rng)); }
> ////////////////////////////////////////////////////////////////////////////
>
> And now here's something similar written in C++ and using the Boost
> RNGs:
>
> ////////////////////////////////////////////////////////////////////////////
> #include <iostream>
> #include <iomanip>
> #include <boost/random.hpp>
>
> int main(void)
> {
> boost::mt19937 rng(12345);
>
> for(int i=0;i<10;++i)
> std::cout << rng() << std::endl;
>
> std::cout << std::endl;
> std::cout << "Min: " << rng.min() << std::endl;
> std::cout << "Max: " << rng.max() << std::endl;
> std::cout << std::endl;
>
> rng.seed(12345);
>
> for(int i=0;i<10;++i)
> std::cout << std::setprecision(64) <<
> boost::uniform_real<double>(0.0, 1.0)(rng) << std::endl;
> }
> ////////////////////////////////////////////////////////////////////////////
>
> When I run these on my 64-bit machine I get different results for the
> uniform doubles, which show up round about the 15th or 16th decimal
> place.
>
> If I replace double with float, I get a similar result, but now with
> the difference starting at about the 7th or 8th decimal place.
>
> I've tried tweaking the internals of std.random's uniform() just to
> confirm it's not a rounding error down to subtly different
> arithmetical order; D's results remain unchanged. So I'm curious why
> I see these differences -- OK, floating point is a minefield, but I
> thought these were hardware-implemented variables and operations
> which I'd expect to match between C++ and D.
>
> OK, it's not the end of the world and these numbers are identical to
> a high degree of accuracy -- but I'm just curious as to why the
> difference. It's also slightly frustrating to not have precise
> agreement between the output of 2 libraries that are so obviously
> designed to produce an identical API and feature set.
>
> Best wishes,
>
> -- Joe
My (limited) understanding is that it's almost practically impossible to
get consistency in x86 floating point unless you're using SSE:
http://www.yosefk.com/blog/consistency-how-to-defeat-the-purpose-of-ieee-floating-point.html
Maybe the effect you're observing could be related to what he
describes?
More information about the Digitalmars-d
mailing list