double RoundToReasonable(double v, int Units) {
  if (Units == 1) {
    if (v < 0)
      return ((int)(-v * 1e6 + 0.5)) / -1e6;
    else
      return ((int)(v * 1e6 + 0.5)) / 1e6;
  } else {
    if (v < 0)
      return ((int)(-v * 1e4 + 0.5)) / -1e4;
    else
      return ((int)(v * 1e4 + 0.5)) / 1e4;
  }
}


x86 assembly (clang, -O0):
<RoundToReasonable>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x10(%rbp)
mov    %edi,-0x14(%rbp)
cmpl   $0x1,-0x14(%rbp)
jne    11b1 <RoundToReasonable+0xb1>
xorps  %xmm0,%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    1176 <RoundToReasonable+0x76>
movsd  -0x10(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  0xed0(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xeb4(%rip),%xmm1
addsd  %xmm1,%xmm0
cvttsd2si %xmm0,%eax
cvtsi2sd %eax,%xmm0
movsd  0xeb8(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1247 <RoundToReasonable+0x147>
movsd  -0x10(%rbp),%xmm0
movsd  0xe95(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe79(%rip),%xmm1
addsd  %xmm1,%xmm0
cvttsd2si %xmm0,%eax
cvtsi2sd %eax,%xmm0
movsd  0xe75(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1247 <RoundToReasonable+0x147>
xorps  %xmm0,%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    1211 <RoundToReasonable+0x111>
movsd  -0x10(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  0xe1d(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe19(%rip),%xmm1
addsd  %xmm1,%xmm0
cvttsd2si %xmm0,%eax
cvtsi2sd %eax,%xmm0
movsd  0xe0d(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1247 <RoundToReasonable+0x147>
movsd  -0x10(%rbp),%xmm0
movsd  0xde2(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xdde(%rip),%xmm1
addsd  %xmm1,%xmm0
cvttsd2si %xmm0,%eax
cvtsi2sd %eax,%xmm0
movsd  0xdc2(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<RoundToReasonable>:
xorpd  %xmm1,%xmm1
cmp    $0x1,%edi
jne    1119 <RoundToReasonable+0x19>
ucomisd %xmm0,%xmm1
jbe    1129 <RoundToReasonable+0x29>
movsd  0xf09(%rip),%xmm1
jmp    113b <RoundToReasonable+0x3b>
ucomisd %xmm0,%xmm1
jbe    1133 <RoundToReasonable+0x33>
movsd  0xee9(%rip),%xmm1
jmp    113b <RoundToReasonable+0x3b>
movsd  0xee7(%rip),%xmm1
jmp    113b <RoundToReasonable+0x3b>
movsd  0xec5(%rip),%xmm1
mulsd  %xmm1,%xmm0
addsd  0xec1(%rip),%xmm0
cvttpd2dq %xmm0,%xmm0
cvtdq2pd %xmm0,%xmm0
divsd  %xmm1,%xmm0
ret

LLVM IR (-O0):
define double @RoundToReasonable(double %0, i32 %1) {
%3 = alloca double
%4 = alloca double
%5 = alloca i32
store double %0, double* %4
store i32 %1, i32* %5
%6 = load i32, i32* %5
%7 = icmp eq i32 %6, 1
br i1 %7, label %8, label %24
8: ; preds = %2
%9 = load double, double* %4
%10 = fcmp olt double %9, 0.000000e+00
br i1 %10, label %11, label %18
11: ; preds = %8
%12 = load double, double* %4
%13 = fneg double %12
%14 = call double @llvm.fmuladd.f64(double %13, double 1.000000e+06, double 5.000000e-01)
%15 = fptosi double %14 to i32
%16 = sitofp i32 %15 to double
%17 = fdiv double %16, -1.000000e+06
store double %17, double* %3
br label %40
18: ; preds = %8
%19 = load double, double* %4
%20 = call double @llvm.fmuladd.f64(double %19, double 1.000000e+06, double 5.000000e-01)
%21 = fptosi double %20 to i32
%22 = sitofp i32 %21 to double
%23 = fdiv double %22, 1.000000e+06
store double %23, double* %3
br label %40
24: ; preds = %2
%25 = load double, double* %4
%26 = fcmp olt double %25, 0.000000e+00
br i1 %26, label %27, label %34
27: ; preds = %24
%28 = load double, double* %4
%29 = fneg double %28
%30 = call double @llvm.fmuladd.f64(double %29, double 1.000000e+04, double 5.000000e-01)
%31 = fptosi double %30 to i32
%32 = sitofp i32 %31 to double
%33 = fdiv double %32, -1.000000e+04
store double %33, double* %3
br label %40
34: ; preds = %24
%35 = load double, double* %4
%36 = call double @llvm.fmuladd.f64(double %35, double 1.000000e+04, double 5.000000e-01)
%37 = fptosi double %36 to i32
%38 = sitofp i32 %37 to double
%39 = fdiv double %38, 1.000000e+04
store double %39, double* %3
br label %40
40: ; preds = %34, %27, %18, %11
%41 = load double, double* %3
ret double %41
}

LLVM IR (-O2):
define double @RoundToReasonable(double %0, i32 %1) {
%3 = icmp eq i32 %1, 1
%4 = fcmp olt double %0, 0.000000e+00
br i1 %3, label %5, label %11
5: ; preds = %2
br i1 %4, label %6, label %9
6: ; preds = %5
%7 = fneg double %0
%8 = tail call double @llvm.fmuladd.f64(double %7, double 1.000000e+06, double 5.000000e-01)
br label %17
9: ; preds = %5
%10 = tail call double @llvm.fmuladd.f64(double %0, double 1.000000e+06, double 5.000000e-01)
br label %17
11: ; preds = %2
br i1 %4, label %12, label %15
12: ; preds = %11
%13 = fneg double %0
%14 = tail call double @llvm.fmuladd.f64(double %13, double 1.000000e+04, double 5.000000e-01)
br label %17
15: ; preds = %11
%16 = tail call double @llvm.fmuladd.f64(double %0, double 1.000000e+04, double 5.000000e-01)
br label %17
17: ; preds = %15, %12, %9, %6
%18 = phi double [ %16, %15 ], [ %14, %12 ], [ %10, %9 ], [ %8, %6 ]
%19 = phi double [ 1.000000e+04, %15 ], [ -1.000000e+04, %12 ], [ 1.000000e+06, %9 ], [ -1.000000e+06, %6 ]
%20 = fptosi double %18 to i32
%21 = sitofp i32 %20 to double
%22 = fdiv double %21, %19
ret double %22
}