1aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner#include <stdio.h>
2aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner#include <stdlib.h>
3aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner
4aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turnerdouble drand48(void);
5aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner
6aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turnerstatic int fails = 0;
7aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner
8aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turnerstatic int
9aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turnerdouble_eq(double a, double b)
10aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner{
11aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    /* Compare two double values, and return 1 if they are "close" enough */
12aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    double diff = a -b;
13aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    if (diff < 0) diff = -diff;
14aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    if (a < 0) {
15aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner        if (b >= 0)
16aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner            return 0;
17aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner        a = -a;
18aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner        b = -b;
19aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    } else if (b < 0) {
20aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner        return 0;
21aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    }
22aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    if (a >= b)
23aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner        a = b;
24aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner
25aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    return diff < a*1e-8;
26aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner}
27aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner
28aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner#define EXPECT_LONG(value,expected) \
29aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    do { \
30aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner        long _val = (value); \
31aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner        long _expected = (expected); \
32aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner        printf( "%s: ", #value); \
33aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner        if (_val != _expected) { \
34aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner            printf("KO: %ld (%ld expected)\n", _val, _expected); \
35aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner            fails += 1; \
36aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner        } else { \
37aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner            printf("%ld (ok)\n", _expected); \
38aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner        } \
39aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    } while (0)
40aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner
41aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner#define EXPECT_DOUBLE(value,expected) \
42aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    do { \
43aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner        double _val = (value); \
44aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner        double _expected = (expected); \
45aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner        printf( "%s: ", #value); \
46aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner        if (!double_eq(_val,_expected)) { \
47aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner            printf("KO: %.12g (%.12g expected)\n", _val, _expected); \
48aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner            fails += 1; \
49aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner        } else { \
50aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner            printf("%.12g (ok)\n", _expected); \
51aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner        } \
52aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    } while (0)
53aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner
54aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turnerint
55aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turnermain(void)
56aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner{
57aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    long int l = -345678L;
58aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    float  f = 123.456e14;
59aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    double d = -87.65432e45;
60aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner
61aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    // Verify display of hard-coded float and double values.
62aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    // This is done to confirm the correct printf format specifiers
63aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    // are being used.
64aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    puts("Hard-coded values");
65aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    printf("  l: %li\n", l);
66aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    printf("  f: %g\n", (double) f);
67aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    printf("  d: %g\n", d);
68aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner
69aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    // lrand48
70aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    puts("lrand48");
71aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    puts("  srand48(100)");
72aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    srand48(100);
73aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    EXPECT_LONG(lrand48(),539144888);
74aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    EXPECT_LONG(lrand48(),448713282);
75aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    EXPECT_LONG(lrand48(),2020627300);
76aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner
77aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    // Try again, with same seed.  Should get the same values
78aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    puts("  srand48(100)");
79aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    srand48(100);
80aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    EXPECT_LONG(lrand48(),539144888);
81aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    EXPECT_LONG(lrand48(),448713282);
82aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    EXPECT_LONG(lrand48(),2020627300);
83aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner
84aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    // Try again, but with a different seed
85aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    puts("  srand48(101)");
86aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    srand48(101);
87aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    EXPECT_LONG(lrand48(),261694958);
88aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    EXPECT_LONG(lrand48(),1961809783);
89aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    EXPECT_LONG(lrand48(),1458943423);
90aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner
91aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    // drand48
92aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    puts("drand48");
93aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    puts("  srand48(100)");
94aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    srand48(100);
95aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    EXPECT_DOUBLE(drand48(),0.251058902665);
96aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    EXPECT_DOUBLE(drand48(),0.208948404851);
97aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    EXPECT_DOUBLE(drand48(),0.940927909958);
98aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner
99aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    // Try again, with same seed.  Should get the same values
100aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    puts("  srand48(100)");
101aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    srand48(100);
102aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    EXPECT_DOUBLE(drand48(),0.251058902665);
103aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    EXPECT_DOUBLE(drand48(),0.208948404851);
104aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    EXPECT_DOUBLE(drand48(),0.940927909958);
105aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner
106aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    // Try again, but with a different seed
107aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    puts("  srand48(101)");
108aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    srand48(101);
109aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    EXPECT_DOUBLE(drand48(),0.121861211331);
110aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    EXPECT_DOUBLE(drand48(),0.913538869095);
111aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    EXPECT_DOUBLE(drand48(),0.679373472502);
112aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner
113aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner    return (fails > 0) ? 1 : 0;
114aa47f0c8ebe0ee3fc6e6ab90b81848efb4c011a8David 'Digit' Turner}
115