Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 124 lines (94 sloc) 3.136 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
use v6;

use Test;
BEGIN { @*INC.push('t/spec/packages') };
use Test::Util;

plan 115;

=begin pod

Basic tests for the rand builtin

=end pod

# L<S32::Numeric/Numeric/"=item rand">

ok(rand >= 0, 'rand returns numbers greater than or equal to 0');
ok(rand < 1, 'rand returns numbers less than 1');

sub test_rand_range(Int $num) {
  for 1..20 {
    my $result = $num.rand;
    ok($num > $result >= 0, "rand returns numbers in [0, $num)");
  }
}

test_rand_range(2);
test_rand_range(3);
test_rand_range(5);
test_rand_range(7);
test_rand_range(11);

# L<S32::Numeric/Real/"=item srand">

lives_ok { srand(1) }, 'srand(1) lives and parses';

{
    my sub repeat_rand ($seed) {
        srand($seed);
        for 1..99 { rand; }
        return rand;
    }

    ok(repeat_rand(314159) == repeat_rand(314159),
        'srand() provides repeatability for rand');

    ok(repeat_rand(0) == repeat_rand(0),
        'edge case: srand(0) provides repeatability');

    ok(repeat_rand(0) != repeat_rand(1),
        'edge case: srand(0) not the same as srand(1)');
}

{
    my sub repeat_rand ($seed) {
        srand($seed);
        for 1..99 { rand; }
        return rand;
    }

    ok(repeat_rand(314159) == repeat_rand(314159),
        'srand(...) provides repeatability for rand');

    ok(repeat_rand(0) == repeat_rand(0),
        'edge case: srand(0) provides repeatability');

    ok(repeat_rand(0) != repeat_rand(1),
        'edge case: srand(0) not the same as srand(:seed(1))');
}

#?rakudo skip 'Test is too slow'
#?niecza skip 'Test is too slow'
# Similar code under Perl 5 runs in < 15s.
{
    srand;

    my $cells = 2 ** 16; # possible values from rand()
    my $samples = 500 * $cells; # how many rand() calls we'll make
    my $freq_wanted = $samples / $cells; # ideal samples per cell
# my @freq_observed[$cells];
    my @freq_observed;

    @freq_observed[ $cells.rand ]++ for 1 .. $samples;

    my $cs = 0;
    for @freq_observed -> $obsfreq {
        $cs += (($obsfreq // 0) - $freq_wanted) ** 2;
    }
    $cs /= $freq_wanted;

    my $badness = abs( 1 - $cs / ( $cells - 1 ) );

    # XXX: My confidence in this test is rather low.
    # I got the number below by running the same test repeatedly with Perl 5
    # and observing its results then again with deliberately corrupted
    # "results". The value I picked is between the worst of the natural
    # results and the best of the b0rked results.
    # My hope is that someone who understands Chi Squared tests
    # better than I do will find what I've written easier to fix
    # than to write a good test from scratch.
    # The good news is it passes with Rakudo when I cut down on $samples
    # and wait a while.

    ok( $badness < 0.15, 'rand is pretty random' );
}

{
    # this catches if the random number generator is biased toward
    # smaller numbers in a range.
    my %h;
    %h{$_}++ for (^5).roll(1000);
    ok %h<3> + %h<4> > 300, "Distribution is not very uneven";
}

# RT #113968
#?niecza skip "throws_like"
#?DOES 4
{
    throws_like 'rand()', X::Obsolete;
    throws_like 'rand(3)', X::Obsolete;
}

# vim: ft=perl6
Something went wrong with that request. Please try again.