Skip to content

Instantly share code, notes, and snippets.

@mjambon
Created May 20, 2011 23:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mjambon/983995 to your computer and use it in GitHub Desktop.
Save mjambon/983995 to your computer and use it in GitHub Desktop.
Print a float using the engineering notation, where the exponent is a multiple of 3
(*
Print a float using the engineering notation.
The representation is approximate in the sense that it does not always allow
to recover the original float by parsing the result.
nan
inf
-inf
0
1
-1
2
-2
9.9
10
999.999
1e3
1.000001e3
999.999999e3
1.000000001e6
12.345678e6
123.456789e6
1.23456789e9
0.001
999e-6
999.9e-6
1e-6
999e-9
999.9e-9
*)
open Printf
let eng x =
match classify_float x with
FP_zero -> "0"
| FP_infinite
| FP_nan -> sprintf "%f" x
| FP_normal
| FP_subnormal ->
if x = 0. then "0"
else
let absx = abs_float x in
if absx < 1000. && absx >= 0.001 then
sprintf "%g" x
else
let a = int_of_float (floor (log10 absx)) in
let b =
if a mod 3 = 0 then a
else
if a >= 0 then
3 * (a / 3)
else
3 * (a / 3) - 3
in
let c = absx /. (10. ** float b) in
sprintf "%s%.15ge%i"
(if x < 0. then "-" else "")
c
b
let test () =
List.iter (fun x -> printf "%-15s %s\n" (string_of_float x) (eng x))
[
nan;
infinity;
neg_infinity;
0.;
1.;
-1.;
2.;
-2.;
9.9;
10.;
999.999;
1000.;
1000.001;
999999.999;
1000000.001;
12345678.;
123456789.;
1234567890.;
0.001;
0.000999;
0.0009999;
0.000001;
0.000000999;
0.0000009999;
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment