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