double rand_val(int seed) {
  const long a = 16807;
  const long m = 2147483647;
  const long q = 127773;
  const long r = 2836;
  static long x;
  long x_div_q;
  long x_mod_q;
  long x_new;
  if (seed != 0)
    x = seed;
  x_div_q = x / q;
  x_mod_q = x % q;
  x_new = (a * x_mod_q) - (r * x_div_q);
  if (x_new > 0)
    x = x_new;
  else
    x = x_new + m;
  return ((double)x / m);
}


x86 assembly (clang, -O0):
<rand_val>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
movq   $0x41a7,-0x10(%rbp)
movq   $0x7fffffff,-0x18(%rbp)
7f
movq   $0x1f31d,-0x20(%rbp)
movq   $0xb14,-0x28(%rbp)
cmpl   $0x0,-0x4(%rbp)
je     113c <rand_val+0x3c>
movslq -0x4(%rbp),%rax
mov    %rax,0x2eec(%rip)
mov    0x2ee5(%rip),%rax
mov    $0x1f31d,%ecx
cqto
idiv   %rcx
mov    %rax,-0x30(%rbp)
mov    0x2ed0(%rip),%rax
mov    $0x1f31d,%ecx
cqto
idiv   %rcx
mov    %rdx,-0x38(%rbp)
imul   $0x41a7,-0x38(%rbp),%rax
imul   $0xb14,-0x30(%rbp),%rcx
sub    %rcx,%rax
mov    %rax,-0x40(%rbp)
cmpq   $0x0,-0x40(%rbp)
jle    1198 <rand_val+0x98>
mov    -0x40(%rbp),%rax
mov    %rax,0x2e95(%rip)
jmp    11a9 <rand_val+0xa9>
mov    -0x40(%rbp),%rax
add    $0x7fffffff,%rax
mov    %rax,0x2e7f(%rip)
cvtsi2sdq 0x2e76(%rip),%xmm0
movsd  0xe46(%rip),%xmm1
divsd  %xmm1,%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<rand_val>:
test   %edi,%edi
jne    110d <rand_val+0xd>
mov    0x2f1d(%rip),%rcx
jmp    1110 <rand_val+0x10>
movslq %edi,%rcx
movabs $0x41a705af1fe3fb79,%rdx
05 a7 41
mov    %rcx,%rax
imul   %rdx
mov    %rdx,%rax
shr    $0x3f,%rax
sar    $0xf,%rdx
add    %rax,%rdx
imul   $0x1f31d,%rdx,%rax
sub    %rax,%rcx
imul   $0x41a7,%rcx,%rax
imul   $0xfffffffffffff4ec,%rdx,%rcx
lea    (%rcx,%rax,1),%rdx
test   %rdx,%rdx
lea    0x7fffffff(%rcx,%rax,1),%rax
7f
cmovg  %rdx,%rax
mov    %rax,0x2ec8(%rip)
cvtsi2sd %rax,%xmm0
divsd  0xe93(%rip),%xmm0
ret

LLVM IR (-O0):
@rand_val.x = internal global i64 0
define double @rand_val(i32 %0) {
%2 = alloca i32
%3 = alloca i64
%4 = alloca i64
%5 = alloca i64
%6 = alloca i64
%7 = alloca i64
%8 = alloca i64
%9 = alloca i64
store i32 %0, i32* %2
store i64 16807, i64* %3
store i64 2147483647, i64* %4
store i64 127773, i64* %5
store i64 2836, i64* %6
%10 = load i32, i32* %2
%11 = icmp ne i32 %10, 0
br i1 %11, label %12, label %15
12: ; preds = %1
%13 = load i32, i32* %2
%14 = sext i32 %13 to i64
store i64 %14, i64* @rand_val.x
br label %15
15: ; preds = %12, %1
%16 = load i64, i64* @rand_val.x
%17 = sdiv i64 %16, 127773
store i64 %17, i64* %7
%18 = load i64, i64* @rand_val.x
%19 = srem i64 %18, 127773
store i64 %19, i64* %8
%20 = load i64, i64* %8
%21 = mul nsw i64 16807, %20
%22 = load i64, i64* %7
%23 = mul nsw i64 2836, %22
%24 = sub nsw i64 %21, %23
store i64 %24, i64* %9
%25 = load i64, i64* %9
%26 = icmp sgt i64 %25, 0
br i1 %26, label %27, label %29
27: ; preds = %15
%28 = load i64, i64* %9
store i64 %28, i64* @rand_val.x
br label %32
29: ; preds = %15
%30 = load i64, i64* %9
%31 = add nsw i64 %30, 2147483647
store i64 %31, i64* @rand_val.x
br label %32
32: ; preds = %29, %27
%33 = load i64, i64* @rand_val.x
%34 = sitofp i64 %33 to double
%35 = fdiv double %34, 0x41DFFFFFFFC00000
ret double %35
}

LLVM IR (-O2):
@rand_val.x = internal unnamed_addr global i64 0
define double @rand_val(i32 %0) {
%2 = icmp eq i32 %0, 0
%3 = load i64, i64* @rand_val.x
%4 = sext i32 %0 to i64
%5 = select i1 %2, i64 %3, i64 %4
%6 = sdiv i64 %5, 127773
%7 = srem i64 %5, 127773
%8 = mul nsw i64 %7, 16807
%9 = mul nsw i64 %6, -2836
%10 = add nsw i64 %9, %8
%11 = icmp sgt i64 %10, 0
%12 = add nsw i64 %10, 2147483647
%13 = select i1 %11, i64 %10, i64 %12
store i64 %13, i64* @rand_val.x
%14 = sitofp i64 %13 to double
%15 = fdiv double %14, 0x41DFFFFFFFC00000
ret double %15
}