char *eng(double value, int digits, int numeric) {
  static const char *prefix[] = {"y", "z", "a", "f", "p", "n", "u", "m", "",
                                 "k", "M", "G", "T", "P", "E", "Z", "Y"};
  int expof10;
  static char result[100];
  char *res = result;
  if (value < 0.) {
    *res++ = '-';
    value = -value;
  }
  expof10 = (int)log10(value);
  if (expof10 > 0)
    expof10 = (expof10 / 3) * 3;
  else
    expof10 = (-expof10 + 3) / 3 * (-3);
  value *= pow(10, -expof10);
  if (value >= 1000.) {
    value /= 1000.0;
    expof10 += 3;
  } else if (value >= 100.0)
    digits -= 2;
  else if (value >= 10.0)
    digits -= 1;
  if (numeric || (expof10 < (-24)) ||
      (expof10 > ((-24) + (int)((sizeof(prefix) / sizeof(char *) - 1) * 3))))
    sprintf(res, "%.*fe%d", digits - 1, value, expof10);
  else
    sprintf(res, "%.*f %s", digits - 1, value, prefix[(expof10 - (-24)) / 3]);
  return result;
}


x86 assembly (clang, -O0):
<eng>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
movsd  %xmm0,-0x8(%rbp)
mov    %edi,-0xc(%rbp)
mov    %esi,-0x10(%rbp)
lea    0x2f96(%rip),%rax
mov    %rax,-0x20(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x8(%rbp),%xmm0
jbe    118f <eng+0x5f>
mov    -0x20(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x20(%rbp)
movb   $0x2d,(%rax)
movsd  -0x8(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
call   1040 <log10@plt>
cvttsd2si %xmm0,%eax
mov    %eax,-0x14(%rbp)
cmpl   $0x0,-0x14(%rbp)
jle    11c0 <eng+0x90>
mov    -0x14(%rbp),%eax
mov    $0x3,%ecx
cltd
idiv   %ecx
imul   $0x3,%eax,%eax
mov    %eax,-0x14(%rbp)
jmp    11d6 <eng+0xa6>
xor    %eax,%eax
sub    -0x14(%rbp),%eax
add    $0x3,%eax
mov    $0x3,%ecx
cltd
idiv   %ecx
imul   $0xfffffffd,%eax,%eax
mov    %eax,-0x14(%rbp)
xor    %eax,%eax
sub    -0x14(%rbp),%eax
cvtsi2sd %eax,%xmm1
movsd  0xe21(%rip),%xmm0
call   1030 <pow@plt>
mulsd  -0x8(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
movsd  0xdfd(%rip),%xmm1
ucomisd %xmm1,%xmm0
jb     1231 <eng+0x101>
movsd  -0x8(%rbp),%xmm0
movsd  0xde6(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
mov    -0x14(%rbp),%eax
add    $0x3,%eax
mov    %eax,-0x14(%rbp)
jmp    1280 <eng+0x150>
movsd  -0x8(%rbp),%xmm0
movsd  0xdd2(%rip),%xmm1
ucomisd %xmm1,%xmm0
jb     1256 <eng+0x126>
mov    -0xc(%rbp),%eax
sub    $0x2,%eax
mov    %eax,-0xc(%rbp)
jmp    127b <eng+0x14b>
movsd  -0x8(%rbp),%xmm0
movsd  0xda5(%rip),%xmm1
ucomisd %xmm1,%xmm0
jb     1276 <eng+0x146>
mov    -0xc(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    127b <eng+0x14b>
jmp    1280 <eng+0x150>
cmpl   $0x0,-0x10(%rbp)
jne    129e <eng+0x16e>
cmpl   $0xffffffe8,-0x14(%rbp)
jl     129e <eng+0x16e>
cmpl   $0x18,-0x14(%rbp)
jle    12c3 <eng+0x193>
mov    -0x20(%rbp),%rdi
mov    -0xc(%rbp),%edx
sub    $0x1,%edx
movsd  -0x8(%rbp),%xmm0
mov    -0x14(%rbp),%ecx
lea    0xd81(%rip),%rsi
mov    $0x1,%al
call   1050 <sprintf@plt>
jmp    1302 <eng+0x1d2>
mov    -0x20(%rbp),%rdi
mov    -0xc(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x24(%rbp)
movsd  -0x8(%rbp),%xmm0
mov    -0x14(%rbp),%eax
sub    $0xffffffe8,%eax
mov    $0x3,%ecx
cltd
idiv   %ecx
mov    -0x24(%rbp),%edx
movslq %eax,%rcx
lea    0x2d50(%rip),%rax
mov    (%rax,%rcx,8),%rcx
lea    0xd45(%rip),%rsi
mov    $0x1,%al
call   1050 <sprintf@plt>
lea    0x2dd7(%rip),%rax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<eng>:
push   %rbp
push   %r15
push   %r14
push   %rbx
sub    $0x18,%rsp
mov    %esi,%r15d
mov    %edi,%ebx
xorpd  %xmm1,%xmm1
ucomisd %xmm0,%xmm1
jbe    1161 <eng+0x31>
movb   $0x2d,0x2f00(%rip)
xorpd  0xea8(%rip),%xmm0
lea    0x2ef2(%rip),%r14
jmp    1168 <eng+0x38>
lea    0x2ee8(%rip),%r14
movapd %xmm0,(%rsp)
call   1040 <log10@plt>
cvttsd2si %xmm0,%eax
test   %eax,%eax
jle    118e <eng+0x5e>
mov    %eax,%eax
mov    $0xaaaaaaab,%ecx
imul   %rax,%rcx
shr    $0x21,%rcx
lea    (%rcx,%rcx,2),%ebp
jmp    11b5 <eng+0x85>
mov    $0x3,%ecx
sub    %eax,%ecx
movslq %ecx,%rax
imul   $0x55555556,%rax,%rcx
mov    %rcx,%rdx
shr    $0x3f,%rdx
shr    $0x20,%rcx
add    %edx,%ecx
lea    (%rcx,%rcx,2),%ecx
mov    %eax,%ebp
sub    %ecx,%ebp
sub    %eax,%ebp
mov    %ebp,%eax
neg    %eax
xorps  %xmm1,%xmm1
cvtsi2sd %eax,%xmm1
movsd  0xe48(%rip),%xmm0
call   1030 <pow@plt>
movapd (%rsp),%xmm1
mulsd  %xmm0,%xmm1
ucomisd 0xe3a(%rip),%xmm1
jae    11f9 <eng+0xc9>
ucomisd 0xe38(%rip),%xmm1
jae    1206 <eng+0xd6>
ucomisd 0xe1e(%rip),%xmm1
jb     1209 <eng+0xd9>
add    $0xffffffff,%ebx
jmp    1209 <eng+0xd9>
divsd  0xe17(%rip),%xmm1
add    $0x3,%ebp
jmp    1209 <eng+0xd9>
add    $0xfffffffe,%ebx
add    $0xffffffff,%ebx
test   %r15d,%r15d
jne    1256 <eng+0x126>
cmp    $0xffffffe8,%ebp
jl     1256 <eng+0x126>
cmp    $0x19,%ebp
jge    1256 <eng+0x126>
add    $0x18,%bpl
movzbl %bpl,%eax
imul   $0xab,%eax,%eax
shr    $0x7,%eax
and    $0xfffffffc,%eax
lea    0xdf2(%rip),%rdx
movslq (%rax,%rdx,1),%rcx
add    %rdx,%rcx
lea    0xe50(%rip),%rsi
mov    %r14,%rdi
mov    %ebx,%edx
movapd %xmm1,%xmm0
mov    $0x1,%al
call   1050 <sprintf@plt>
jmp    126f <eng+0x13f>
lea    0xe2f(%rip),%rsi
mov    %r14,%rdi
mov    %ebx,%edx
movapd %xmm1,%xmm0
mov    %ebp,%ecx
mov    $0x1,%al
call   1050 <sprintf@plt>
lea    0x2dda(%rip),%rax
add    $0x18,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@eng.prefix = internal global [17 x i8*] [i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.2, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.4, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.5, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.6, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.7, i32 0, i32 0), i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.8, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.9, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.10, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.11, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.12, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.13, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.14, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.15, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.16, i32 0, i32 0)]
@.str = [2 x i8] c"y\00"
@.str.1 = [2 x i8] c"z\00"
@.str.2 = [2 x i8] c"a\00"
@.str.3 = [2 x i8] c"f\00"
@.str.4 = [2 x i8] c"p\00"
@.str.5 = [2 x i8] c"n\00"
@.str.6 = [2 x i8] c"u\00"
@.str.7 = [2 x i8] c"m\00"
@.str.8 = [1 x i8] zeroinitializer
@.str.9 = [2 x i8] c"k\00"
@.str.10 = [2 x i8] c"M\00"
@.str.11 = [2 x i8] c"G\00"
@.str.12 = [2 x i8] c"T\00"
@.str.13 = [2 x i8] c"P\00"
@.str.14 = [2 x i8] c"E\00"
@.str.15 = [2 x i8] c"Z\00"
@.str.16 = [2 x i8] c"Y\00"
@eng.result = internal global [100 x i8] zeroinitializer
@.str.17 = [8 x i8] c"%.*fe%d\00"
@.str.18 = [8 x i8] c"%.*f %s\00"
define i8* @eng(double %0, i32 %1, i32 %2) {
%4 = alloca double
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i8*
store double %0, double* %4
store i32 %1, i32* %5
store i32 %2, i32* %6
store i8* getelementptr inbounds ([100 x i8], [100 x i8]* @eng.result, i64 0, i64 0), i8** %8
%9 = load double, double* %4
%10 = fcmp olt double %9, 0.000000e+00
br i1 %10, label %11, label %16
11: ; preds = %3
%12 = load i8*, i8** %8
%13 = getelementptr inbounds i8, i8* %12, i32 1
store i8* %13, i8** %8
store i8 45, i8* %12
%14 = load double, double* %4
%15 = fneg double %14
store double %15, double* %4
br label %16
16: ; preds = %11, %3
%17 = load double, double* %4
%18 = call double @log10(double %17)
%19 = fptosi double %18 to i32
store i32 %19, i32* %7
%20 = load i32, i32* %7
%21 = icmp sgt i32 %20, 0
br i1 %21, label %22, label %26
22: ; preds = %16
%23 = load i32, i32* %7
%24 = sdiv i32 %23, 3
%25 = mul nsw i32 %24, 3
store i32 %25, i32* %7
br label %32
26: ; preds = %16
%27 = load i32, i32* %7
%28 = sub nsw i32 0, %27
%29 = add nsw i32 %28, 3
%30 = sdiv i32 %29, 3
%31 = mul nsw i32 %30, -3
store i32 %31, i32* %7
br label %32
32: ; preds = %26, %22
%33 = load i32, i32* %7
%34 = sub nsw i32 0, %33
%35 = sitofp i32 %34 to double
%36 = call double @pow(double 1.000000e+01, double %35)
%37 = load double, double* %4
%38 = fmul double %37, %36
store double %38, double* %4
%39 = load double, double* %4
%40 = fcmp oge double %39, 1.000000e+03
br i1 %40, label %41, label %46
41: ; preds = %32
%42 = load double, double* %4
%43 = fdiv double %42, 1.000000e+03
store double %43, double* %4
%44 = load i32, i32* %7
%45 = add nsw i32 %44, 3
store i32 %45, i32* %7
br label %60
46: ; preds = %32
%47 = load double, double* %4
%48 = fcmp oge double %47, 1.000000e+02
br i1 %48, label %49, label %52
49: ; preds = %46
%50 = load i32, i32* %5
%51 = sub nsw i32 %50, 2
store i32 %51, i32* %5
br label %59
52: ; preds = %46
%53 = load double, double* %4
%54 = fcmp oge double %53, 1.000000e+01
br i1 %54, label %55, label %58
55: ; preds = %52
%56 = load i32, i32* %5
%57 = sub nsw i32 %56, 1
store i32 %57, i32* %5
br label %58
58: ; preds = %55, %52
br label %59
59: ; preds = %58, %49
br label %60
60: ; preds = %59, %41
%61 = load i32, i32* %6
%62 = icmp ne i32 %61, 0
br i1 %62, label %69, label %63
63: ; preds = %60
%64 = load i32, i32* %7
%65 = icmp slt i32 %64, -24
br i1 %65, label %69, label %66
66: ; preds = %63
%67 = load i32, i32* %7
%68 = icmp sgt i32 %67, 24
br i1 %68, label %69, label %76
69: ; preds = %66, %63, %60
%70 = load i8*, i8** %8
%71 = load i32, i32* %5
%72 = sub nsw i32 %71, 1
%73 = load double, double* %4
%74 = load i32, i32* %7
%75 = call i32 (i8*, i8*, ...) @sprintf(i8* %70, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.17, i64 0, i64 0), i32 %72, double %73, i32 %74)
br label %88
76: ; preds = %66
%77 = load i8*, i8** %8
%78 = load i32, i32* %5
%79 = sub nsw i32 %78, 1
%80 = load double, double* %4
%81 = load i32, i32* %7
%82 = sub nsw i32 %81, -24
%83 = sdiv i32 %82, 3
%84 = sext i32 %83 to i64
%85 = getelementptr inbounds [17 x i8*], [17 x i8*]* @eng.prefix, i64 0, i64 %84
%86 = load i8*, i8** %85
%87 = call i32 (i8*, i8*, ...) @sprintf(i8* %77, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.18, i64 0, i64 0), i32 %79, double %80, i8* %86)
br label %88
88: ; preds = %76, %69
ret i8* getelementptr inbounds ([100 x i8], [100 x i8]* @eng.result, i64 0, i64 0)
}

LLVM IR (-O2):
@reltable.eng = internal unnamed_addr constant [17 x i32] [i32 trunc (i64 sub (i64 ptrtoint ([2 x i8]* @.str to i64), i64 ptrtoint ([17 x i32]* @reltable.eng to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([2 x i8]* @.str.1 to i64), i64 ptrtoint ([17 x i32]* @reltable.eng to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([2 x i8]* @.str.2 to i64), i64 ptrtoint ([17 x i32]* @reltable.eng to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([2 x i8]* @.str.3 to i64), i64 ptrtoint ([17 x i32]* @reltable.eng to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([2 x i8]* @.str.4 to i64), i64 ptrtoint ([17 x i32]* @reltable.eng to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([2 x i8]* @.str.5 to i64), i64 ptrtoint ([17 x i32]* @reltable.eng to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([2 x i8]* @.str.6 to i64), i64 ptrtoint ([17 x i32]* @reltable.eng to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([2 x i8]* @.str.7 to i64), i64 ptrtoint ([17 x i32]* @reltable.eng to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([1 x i8]* @.str.8 to i64), i64 ptrtoint ([17 x i32]* @reltable.eng to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([2 x i8]* @.str.9 to i64), i64 ptrtoint ([17 x i32]* @reltable.eng to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([2 x i8]* @.str.10 to i64), i64 ptrtoint ([17 x i32]* @reltable.eng to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([2 x i8]* @.str.11 to i64), i64 ptrtoint ([17 x i32]* @reltable.eng to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([2 x i8]* @.str.12 to i64), i64 ptrtoint ([17 x i32]* @reltable.eng to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([2 x i8]* @.str.13 to i64), i64 ptrtoint ([17 x i32]* @reltable.eng to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([2 x i8]* @.str.14 to i64), i64 ptrtoint ([17 x i32]* @reltable.eng to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([2 x i8]* @.str.15 to i64), i64 ptrtoint ([17 x i32]* @reltable.eng to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([2 x i8]* @.str.16 to i64), i64 ptrtoint ([17 x i32]* @reltable.eng to i64)) to i32)]
@.str = [2 x i8] c"y\00"
@.str.1 = [2 x i8] c"z\00"
@.str.2 = [2 x i8] c"a\00"
@.str.3 = [2 x i8] c"f\00"
@.str.4 = [2 x i8] c"p\00"
@.str.5 = [2 x i8] c"n\00"
@.str.6 = [2 x i8] c"u\00"
@.str.7 = [2 x i8] c"m\00"
@.str.8 = [1 x i8] zeroinitializer
@.str.9 = [2 x i8] c"k\00"
@.str.10 = [2 x i8] c"M\00"
@.str.11 = [2 x i8] c"G\00"
@.str.12 = [2 x i8] c"T\00"
@.str.13 = [2 x i8] c"P\00"
@.str.14 = [2 x i8] c"E\00"
@.str.15 = [2 x i8] c"Z\00"
@.str.16 = [2 x i8] c"Y\00"
@eng.result = internal global [100 x i8] zeroinitializer
@.str.17 = [8 x i8] c"%.*fe%d\00"
@.str.18 = [8 x i8] c"%.*f %s\00"
define i8* @eng(double %0, i32 %1, i32 %2) {
%4 = fcmp olt double %0, 0.000000e+00
br i1 %4, label %5, label %7
5: ; preds = %3
store i8 45, i8* getelementptr inbounds ([100 x i8], [100 x i8]* @eng.result, i64 0, i64 0)
%6 = fneg double %0
br label %7
7: ; preds = %5, %3
%8 = phi double [ %6, %5 ], [ %0, %3 ]
%9 = phi i8* [ getelementptr inbounds ([100 x i8], [100 x i8]* @eng.result, i64 0, i64 1), %5 ], [ getelementptr inbounds ([100 x i8], [100 x i8]* @eng.result, i64 0, i64 0), %3 ]
%10 = tail call double @log10(double %8)
%11 = fptosi double %10 to i32
%12 = icmp sgt i32 %11, 0
br i1 %12, label %13, label %16
13: ; preds = %7
%14 = urem i32 %11, 3
%15 = sub nsw i32 %11, %14
br label %20
16: ; preds = %7
%17 = sub i32 3, %11
%18 = srem i32 %17, 3
%19 = sub i32 %18, %17
br label %20
20: ; preds = %16, %13
%21 = phi i32 [ %15, %13 ], [ %19, %16 ]
%22 = sub nsw i32 0, %21
%23 = sitofp i32 %22 to double
%24 = tail call double @pow(double 1.000000e+01, double %23)
%25 = fmul double %8, %24
%26 = fcmp ult double %25, 1.000000e+03
br i1 %26, label %30, label %27
27: ; preds = %20
%28 = fdiv double %25, 1.000000e+03
%29 = add nsw i32 %21, 3
br label %38
30: ; preds = %20
%31 = fcmp ult double %25, 1.000000e+02
br i1 %31, label %34, label %32
32: ; preds = %30
%33 = add nsw i32 %1, -2
br label %38
34: ; preds = %30
%35 = fcmp ult double %25, 1.000000e+01
br i1 %35, label %38, label %36
36: ; preds = %34
%37 = add nsw i32 %1, -1
br label %38
38: ; preds = %32, %36, %34, %27
%39 = phi i32 [ %1, %27 ], [ %33, %32 ], [ %37, %36 ], [ %1, %34 ]
%40 = phi double [ %28, %27 ], [ %25, %32 ], [ %25, %36 ], [ %25, %34 ]
%41 = phi i32 [ %29, %27 ], [ %21, %32 ], [ %21, %36 ], [ %21, %34 ]
%42 = icmp ne i32 %2, 0
%43 = icmp slt i32 %41, -24
%44 = select i1 %42, i1 true, i1 %43
%45 = icmp sgt i32 %41, 24
%46 = select i1 %44, i1 true, i1 %45
%47 = add nsw i32 %39, -1
br i1 %46, label %48, label %50
48: ; preds = %38
%49 = tail call i32 (i8*, i8*, ...) @sprintf(i8* dereferenceable(1) %9, i8* dereferenceable(1) getelementptr inbounds ([8 x i8], [8 x i8]* @.str.17, i64 0, i64 0), i32 %47, double %40, i32 %41)
br label %58
50: ; preds = %38
%51 = trunc i32 %41 to i8
%52 = add nsw i8 %51, 24
%53 = udiv i8 %52, 3
%54 = zext i8 %53 to i64
%55 = shl i64 %54, 2
%56 = call i8* @llvm.load.relative.i64(i8* bitcast ([17 x i32]* @reltable.eng to i8*), i64 %55)
%57 = tail call i32 (i8*, i8*, ...) @sprintf(i8* dereferenceable(1) %9, i8* dereferenceable(1) getelementptr inbounds ([8 x i8], [8 x i8]* @.str.18, i64 0, i64 0), i32 %47, double %40, i8* %56)
br label %58
58: ; preds = %50, %48
ret i8* getelementptr inbounds ([100 x i8], [100 x i8]* @eng.result, i64 0, i64 0)
}