Created
October 24, 2017 19:17
-
-
Save scurest/89078cd04a0cbbb7a8e8bec77577fca7 to your computer and use it in GitHub Desktop.
Tests rountripping floating-point numbers by printfing them in zig and then scanfing them in C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdint.h> | |
#include <math.h> | |
uint32_t f2i(float x) { return *(uint32_t*)(&x); } | |
float i2f(uint32_t x) { return *(float*)(&x); } | |
int main() { | |
uint32_t i = 0; | |
while (1) { | |
if (!(isnan(i2f(i)) || isinf(i2f(i)))) { | |
float x; | |
if (scanf("%f", &x) != 1) { | |
printf("stopped abruptly on i=%u\n", i); | |
return 1; | |
} | |
if (f2i(x) != i) { | |
printf("failed on i = %u\n", i); | |
return 1; | |
} | |
} | |
if (i == 0x80000000u) break; | |
++i; | |
} | |
printf("ok\n"); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const io = @import("std").io; | |
const math = @import("std").math; | |
pub fn main() -> %void { | |
var i: u32 = 0; | |
while (true) { | |
const x = @bitCast(f32, i); | |
if (!(math.isNan(x) or math.isInf(x))) { | |
%%io.stdout.printf("{}\n", x); | |
} | |
if (i == 0x80000000) break; | |
i += 1; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdint.h> | |
#include <math.h> | |
uint64_t d2l(double x) { return *(uint64_t*)(&x); } | |
double l2d(uint64_t x) { return *(double*)(&x); } | |
//xoroshiro128+ | |
uint64_t s[2]; | |
static inline uint64_t rotl(const uint64_t x, int k) { | |
return (x << k) | (x >> (64 - k)); | |
} | |
uint64_t next(void) { | |
const uint64_t s0 = s[0]; | |
uint64_t s1 = s[1]; | |
const uint64_t result = s0 + s1; | |
s1 ^= s0; | |
s[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b | |
s[1] = rotl(s1, 36); // c | |
return result; | |
} | |
int main() { | |
uint32_t num; | |
if (!scanf("%lu %lu %u", &s[0], &s[1], &num)) { | |
printf("error\n"); | |
return 1; | |
} | |
printf("s[0]=%lu, s[1]=%lu\n", s[0], s[1]); | |
for (uint32_t i = 0; i != num; ++i) { | |
uint64_t val = next(); | |
double x = l2d(val); | |
if (!(isnan(x) || isinf(x))) { | |
double input; | |
if (scanf("%lf", &input) != 1) { | |
printf("stopped abruptly on val=%lu\n", val); | |
return 1; | |
} | |
if (d2l(input) != val) { | |
printf("failed on val = %lu\n", val); | |
return 1; | |
} | |
} | |
} | |
printf("ok\n"); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const io = @import("std").io; | |
const math = @import("std").math; | |
const os = @import("std").os; | |
//xoroshiro128+ | |
var s: [2]u64 = [2]u64 {0, 0}; | |
fn rotl(x: u64, k: u6) -> u64 { | |
(x << k) | (x >> u6((u32(64) - u32(k)))) | |
} | |
fn next() -> u64 { | |
const s0 = s[0]; | |
var s1 = s[1]; | |
const result = s0 +% s1; | |
s1 ^= s0; | |
s[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b | |
s[1] = rotl(s1, 36); // c | |
result | |
} | |
// Convert eight bytes to u64 in LE order. | |
fn buf2u64(b: []u8) -> u64 { | |
var res: u64 = 0; | |
{ var i: usize = 0; while (i != 8) : (i += 1) { | |
res <<= 8; | |
res |= b[i]; | |
}} | |
res | |
} | |
pub fn main() -> %void { | |
var buf: [16]u8 = undefined; | |
%%os.getRandomBytes(buf[0..16]); | |
s[0] = buf2u64(buf[0..8]); | |
s[1] = buf2u64(buf[8..16]); | |
// Number of trials | |
const num: u32 = 1000000; | |
%%io.stdout.printf("{} {} {}\n", s[0], s[1], num); | |
var i: u32 = 0; | |
while (i != num) : (i += 1) { | |
const x = @bitCast(f64, next()); | |
if (!(math.isNan(x) or math.isInf(x))) { | |
%%io.stdout.printf("{}\n", x); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# For exhaustive testing of all positive f32s (+ negative zero) | |
zig build-exe f32-out.zig | |
gcc -O2 f32-in.c -of32-in | |
time ./f32-out | ./f32-in | |
# For random testing of f64 | |
zig build-exe rand-out.zig | |
gcc -O2 rand-in.c -orand-in | |
time ./rand-out | ./rand-in |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment