#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
double copysign(double, double);
double scalbn(double x, int n) {
  int k, hx, lx;
  hx = *(1 + (int *)&x);
  lx = *(int *)&x;
  k = (hx & 0x7ff00000) >> 20;
  if (k == 0) {
    if ((lx | (hx & 0x7fffffff)) == 0) {
      return x;
    }
    x *= 1.80143985094819840000e+16;
    hx = *(1 + (int *)&x);
    k = ((hx & 0x7ff00000) >> 20) - 54;
    if (n < -50000) {
      return 1.0e-300 * x;
    }
  }
  if (k == 0x7ff) {
    return x + x;
  }
  k = k + n;
  if (k > 0x7fe) {
    return 1.0e+300 * copysign(1.0e+300, x);
  }
  if (k > 0) {
    *(1 + (int *)&x) = (hx & 0x800fffff) | (k << 20);
    return x;
  }
  if (k <= -54) {
    if (n > 50000) {
      return 1.0e+300 * copysign(1.0e+300, x);
    } else {
      return 1.0e-300 * copysign(1.0e-300, x);
    }
  }
  k += 54;
  *(1 + (int *)&x) = (hx & 0x800fffff) | (k << 20);
  return x * 5.55111512312578270212e-17;
}


x86 assembly (clang, -O0):
<scalbn>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x10(%rbp)
mov    %edi,-0x14(%rbp)
mov    -0xc(%rbp),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x10(%rbp),%eax
mov    %eax,-0x20(%rbp)
mov    -0x1c(%rbp),%eax
and    $0x7ff00000,%eax
sar    $0x14,%eax
mov    %eax,-0x18(%rbp)
cmpl   $0x0,-0x18(%rbp)
jne    11a8 <scalbn+0xa8>
mov    -0x20(%rbp),%eax
mov    -0x1c(%rbp),%ecx
and    $0x7fffffff,%ecx
or     %ecx,%eax
cmp    $0x0,%eax
jne    1156 <scalbn+0x56>
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12e3 <scalbn+0x1e3>
movsd  0xea2(%rip),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
mov    -0xc(%rbp),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
and    $0x7ff00000,%eax
sar    $0x14,%eax
sub    $0x36,%eax
mov    %eax,-0x18(%rbp)
cmpl   $0xffff3cb0,-0x14(%rbp)
jge    11a3 <scalbn+0xa3>
movsd  0xe7c(%rip),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12e3 <scalbn+0x1e3>
jmp    11a8 <scalbn+0xa8>
cmpl   $0x7ff,-0x18(%rbp)
jne    11c9 <scalbn+0xc9>
movsd  -0x10(%rbp),%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12e3 <scalbn+0x1e3>
mov    -0x18(%rbp),%eax
add    -0x14(%rbp),%eax
mov    %eax,-0x18(%rbp)
cmpl   $0x7fe,-0x18(%rbp)
jle    1210 <scalbn+0x110>
movsd  -0x10(%rbp),%xmm1
movaps 0xe35(%rip),%xmm0
pand   %xmm0,%xmm1
movaps 0xe4a(%rip),%xmm0
por    %xmm0,%xmm1
movsd  0xe16(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12e3 <scalbn+0x1e3>
cmpl   $0x0,-0x18(%rbp)
jle    123c <scalbn+0x13c>
mov    -0x1c(%rbp),%eax
and    $0x800fffff,%eax
mov    -0x18(%rbp),%ecx
shl    $0x14,%ecx
or     %ecx,%eax
mov    %eax,-0xc(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12e3 <scalbn+0x1e3>
cmpl   $0xffffffca,-0x18(%rbp)
jg     12b5 <scalbn+0x1b5>
cmpl   $0xc350,-0x14(%rbp)
jle    1284 <scalbn+0x184>
movsd  -0x10(%rbp),%xmm1
movaps 0xdc1(%rip),%xmm0
pand   %xmm0,%xmm1
movaps 0xdd6(%rip),%xmm0
por    %xmm0,%xmm1
movsd  0xda2(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12e3 <scalbn+0x1e3>
movsd  -0x10(%rbp),%xmm1
movaps 0xd90(%rip),%xmm0
pand   %xmm0,%xmm1
movaps 0xd95(%rip),%xmm0
por    %xmm0,%xmm1
movsd  0xd69(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12e3 <scalbn+0x1e3>
mov    -0x18(%rbp),%eax
add    $0x36,%eax
mov    %eax,-0x18(%rbp)
mov    -0x1c(%rbp),%eax
and    $0x800fffff,%eax
mov    -0x18(%rbp),%ecx
shl    $0x14,%ecx
or     %ecx,%eax
mov    %eax,-0xc(%rbp)
movsd  0xd2f(%rip),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<scalbn>:
movq   %xmm0,%rdx
mov    %rdx,%rax
shr    $0x34,%rax
and    $0x7ff,%eax
cmp    $0x7ff,%eax
je     114a <scalbn+0x4a>
mov    %rdx,%rcx
shr    $0x20,%rcx
test   %eax,%eax
jne    1167 <scalbn+0x67>
and    $0x7fffffff,%ecx
or     %edx,%ecx
je     11fd <scalbn+0xfd>
mulsd  0xec7(%rip),%xmm0
cmp    $0xffff3caf,%edi
jg     114f <scalbn+0x4f>
mulsd  0xebf(%rip),%xmm0
ret
addsd  %xmm0,%xmm0
ret
movq   %xmm0,%rax
mov    %rax,%rcx
shr    $0x20,%rcx
shr    $0x34,%rax
and    $0x7ff,%eax
add    $0xffffffca,%eax
add    %edi,%eax
cmp    $0x7ff,%eax
jl     1189 <scalbn+0x89>
andpd  0xea8(%rip),%xmm0
orpd   0xec0(%rip),%xmm0
mulsd  0xe90(%rip),%xmm0
ret
test   %eax,%eax
jle    11ac <scalbn+0xac>
and    $0x800fffff,%ecx
shl    $0x14,%eax
or     %ecx,%eax
movq   %xmm0,%rcx
shl    $0x20,%rax
mov    %ecx,%ecx
or     %rax,%rcx
movq   %rcx,%xmm0
ret
cmp    $0xffffffca,%eax
jg     11d2 <scalbn+0xd2>
cmp    $0xc351,%edi
jge    1170 <scalbn+0x70>
andpd  0xe5f(%rip),%xmm0
orpd   0xe67(%rip),%xmm0
mulsd  0xe37(%rip),%xmm0
ret
and    $0x800fffff,%ecx
shl    $0x14,%eax
add    $0x3600000,%eax
or     %ecx,%eax
movq   %xmm0,%rcx
shl    $0x20,%rax
mov    %ecx,%ecx
or     %rax,%rcx
movq   %rcx,%xmm0
mulsd  0xe13(%rip),%xmm0
ret

LLVM IR (-O0):
define double @scalbn(double %0, i32 %1) {
%3 = alloca double
%4 = alloca double
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
store double %0, double* %4
store i32 %1, i32* %5
%9 = bitcast double* %4 to i32*
%10 = getelementptr inbounds i32, i32* %9, i64 1
%11 = load i32, i32* %10
store i32 %11, i32* %7
%12 = bitcast double* %4 to i32*
%13 = load i32, i32* %12
store i32 %13, i32* %8
%14 = load i32, i32* %7
%15 = and i32 %14, 2146435072
%16 = ashr i32 %15, 20
store i32 %16, i32* %6
%17 = load i32, i32* %6
%18 = icmp eq i32 %17, 0
br i1 %18, label %19, label %43
19: ; preds = %2
%20 = load i32, i32* %8
%21 = load i32, i32* %7
%22 = and i32 %21, 2147483647
%23 = or i32 %20, %22
%24 = icmp eq i32 %23, 0
br i1 %24, label %25, label %27
25: ; preds = %19
%26 = load double, double* %4
store double %26, double* %3
br label %98
27: ; preds = %19
%28 = load double, double* %4
%29 = fmul double %28, 0x4350000000000000
store double %29, double* %4
%30 = bitcast double* %4 to i32*
%31 = getelementptr inbounds i32, i32* %30, i64 1
%32 = load i32, i32* %31
store i32 %32, i32* %7
%33 = load i32, i32* %7
%34 = and i32 %33, 2146435072
%35 = ashr i32 %34, 20
%36 = sub nsw i32 %35, 54
store i32 %36, i32* %6
%37 = load i32, i32* %5
%38 = icmp slt i32 %37, -50000
br i1 %38, label %39, label %42
39: ; preds = %27
%40 = load double, double* %4
%41 = fmul double 1.000000e-300, %40
store double %41, double* %3
br label %98
42: ; preds = %27
br label %43
43: ; preds = %42, %2
%44 = load i32, i32* %6
%45 = icmp eq i32 %44, 2047
br i1 %45, label %46, label %50
46: ; preds = %43
%47 = load double, double* %4
%48 = load double, double* %4
%49 = fadd double %47, %48
store double %49, double* %3
br label %98
50: ; preds = %43
%51 = load i32, i32* %6
%52 = load i32, i32* %5
%53 = add nsw i32 %51, %52
store i32 %53, i32* %6
%54 = load i32, i32* %6
%55 = icmp sgt i32 %54, 2046
br i1 %55, label %56, label %60
56: ; preds = %50
%57 = load double, double* %4
%58 = call double @llvm.copysign.f64(double 1.000000e+300, double %57)
%59 = fmul double 1.000000e+300, %58
store double %59, double* %3
br label %98
60: ; preds = %50
%61 = load i32, i32* %6
%62 = icmp sgt i32 %61, 0
br i1 %62, label %63, label %72
63: ; preds = %60
%64 = load i32, i32* %7
%65 = and i32 %64, -2146435073
%66 = load i32, i32* %6
%67 = shl i32 %66, 20
%68 = or i32 %65, %67
%69 = bitcast double* %4 to i32*
%70 = getelementptr inbounds i32, i32* %69, i64 1
store i32 %68, i32* %70
%71 = load double, double* %4
store double %71, double* %3
br label %98
72: ; preds = %60
%73 = load i32, i32* %6
%74 = icmp sle i32 %73, -54
br i1 %74, label %75, label %86
75: ; preds = %72
%76 = load i32, i32* %5
%77 = icmp sgt i32 %76, 50000
br i1 %77, label %78, label %82
78: ; preds = %75
%79 = load double, double* %4
%80 = call double @llvm.copysign.f64(double 1.000000e+300, double %79)
%81 = fmul double 1.000000e+300, %80
store double %81, double* %3
br label %98
82: ; preds = %75
%83 = load double, double* %4
%84 = call double @llvm.copysign.f64(double 1.000000e-300, double %83)
%85 = fmul double 1.000000e-300, %84
store double %85, double* %3
br label %98
86: ; preds = %72
%87 = load i32, i32* %6
%88 = add nsw i32 %87, 54
store i32 %88, i32* %6
%89 = load i32, i32* %7
%90 = and i32 %89, -2146435073
%91 = load i32, i32* %6
%92 = shl i32 %91, 20
%93 = or i32 %90, %92
%94 = bitcast double* %4 to i32*
%95 = getelementptr inbounds i32, i32* %94, i64 1
store i32 %93, i32* %95
%96 = load double, double* %4
%97 = fmul double %96, 0x3C90000000000000
store double %97, double* %3
br label %98
98: ; preds = %86, %82, %78, %63, %56, %46, %39, %25
%99 = load double, double* %3
ret double %99
}

LLVM IR (-O2):
define double @scalbn(double %0, i32 %1) {
%3 = bitcast double %0 to i64
%4 = lshr i64 %3, 32
%5 = trunc i64 %4 to i32
%6 = lshr i32 %5, 20
%7 = and i32 %6, 2047
switch i32 %7, label %26 [
i32 0, label %8
i32 2047, label %24
]
8: ; preds = %2
%9 = trunc i64 %3 to i32
%10 = and i32 %5, 2147483647
%11 = or i32 %10, %9
%12 = icmp eq i32 %11, 0
br i1 %12, label %69, label %13
13: ; preds = %8
%14 = fmul double %0, 0x4350000000000000
%15 = bitcast double %14 to i64
%16 = lshr i64 %15, 32
%17 = trunc i64 %16 to i32
%18 = lshr i32 %17, 20
%19 = and i32 %18, 2047
%20 = add nsw i32 %19, -54
%21 = icmp slt i32 %1, -50000
br i1 %21, label %22, label %26
22: ; preds = %13
%23 = fmul double %14, 1.000000e-300
br label %69
24: ; preds = %2
%25 = fadd double %0, %0
br label %69
26: ; preds = %2, %13
%27 = phi i32 [ %17, %13 ], [ %5, %2 ]
%28 = phi i32 [ %20, %13 ], [ %7, %2 ]
%29 = phi double [ %14, %13 ], [ %0, %2 ]
%30 = add nsw i32 %28, %1
%31 = icmp sgt i32 %30, 2046
br i1 %31, label %32, label %35
32: ; preds = %26
%33 = tail call double @llvm.copysign.f64(double 1.000000e+300, double %29)
%34 = fmul double %33, 1.000000e+300
br label %69
35: ; preds = %26
%36 = icmp sgt i32 %30, 0
br i1 %36, label %37, label %47
37: ; preds = %35
%38 = and i32 %27, -2146435073
%39 = shl nuw nsw i32 %30, 20
%40 = or i32 %39, %38
%41 = bitcast double %29 to i64
%42 = zext i32 %40 to i64
%43 = shl nuw i64 %42, 32
%44 = and i64 %41, 4294967295
%45 = or i64 %43, %44
%46 = bitcast i64 %45 to double
br label %69
47: ; preds = %35
%48 = icmp slt i32 %30, -53
br i1 %48, label %49, label %57
49: ; preds = %47
%50 = icmp sgt i32 %1, 50000
br i1 %50, label %51, label %54
51: ; preds = %49
%52 = tail call double @llvm.copysign.f64(double 1.000000e+300, double %29)
%53 = fmul double %52, 1.000000e+300
br label %69
54: ; preds = %49
%55 = tail call double @llvm.copysign.f64(double 1.000000e-300, double %29)
%56 = fmul double %55, 1.000000e-300
br label %69
57: ; preds = %47
%58 = and i32 %27, -2146435073
%59 = shl nsw i32 %30, 20
%60 = add i32 %59, 56623104
%61 = or i32 %60, %58
%62 = bitcast double %29 to i64
%63 = zext i32 %61 to i64
%64 = shl nuw i64 %63, 32
%65 = and i64 %62, 4294967295
%66 = or i64 %64, %65
%67 = bitcast i64 %66 to double
%68 = fmul double %67, 0x3C90000000000000
br label %69
69: ; preds = %8, %57, %54, %51, %37, %32, %24, %22
%70 = phi double [ %23, %22 ], [ %25, %24 ], [ %34, %32 ], [ %46, %37 ], [ %53, %51 ], [ %56, %54 ], [ %68, %57 ], [ %0, %8 ]
ret double %70
}