123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161open!ImportopenStd_internalmoduleStable=structmoduleV1=structtypet=float[@@derivinghash]letof_multf=fletto_multt=tletof_percentagef=f/.100.letto_percentaget=t*.100.letof_bpf=f/.10_000.letto_bpt=t*.10_000.letof_bp_inti=of_bp(Float.of_inti)letto_bp_intt=Float.to_int(to_bpt)moduleFormat=structtypet=|Exponentofint|Exponent_Eofint|Decimalofint|Ocaml|Compactofint|Compact_Eofint|Hexofint|Hex_Eofint[@@derivingsexp_of]letexponent~precision=Exponentprecisionletexponent_E~precision=Exponent_Eprecisionletdecimal~precision=Decimalprecisionletocaml=Ocamlletcompact~precision=Compactprecisionletcompact_E~precision=Compact_Eprecisionlethex~precision=Hexprecisionlethex_E~precision=Hex_Eprecisionletformat_floatt=matchtwith|Exponentprecision->sprintf"%.*e"precision|Exponent_Eprecision->sprintf"%.*E"precision|Decimalprecision->sprintf"%.*f"precision|Ocaml->sprintf"%F"|Compactprecision->sprintf"%.*g"precision|Compact_Eprecision->sprintf"%.*G"precision|Hexprecision->sprintf"%.*h"precision|Hex_Eprecision->sprintf"%.*H"precision;;endletformatxformat=letx_abs=Float.absxinletstringfloat=Format.format_floatformatfloatinifx_abs=0.then"0x"elseifx_abs>=1.thenstring(x*.1.)^"x"elseifx_abs>=0.01thenstring(x*.100.)^"%"elsestring(x*.10_000.)^"bp";;moduleStringable=structtypet=float(* WARNING - PLEASE READ BEFORE EDITING THESE FUNCTIONS:
The string converters in Stable.V1 should never change. If you are changing the
semantics of anything that affects the sexp or bin-io representation of values of
this type (this includes to_string and of_string) make a Stable.V2 and make your
changes there. Thanks! *)letto_stringx=letx_abs=Float.absxinletstringfloat=sprintf"%.6G"floatinifx_abs=0.then"0x"elseifx_abs>=1.thenstring(x*.1.)^"x"elseifx_abs>=0.01thenstring(x*.100.)^"%"elsestring(x*.10_000.)^"bp";;letreally_of_stringstrfloat_of_string=matchString.chop_suffixstr~suffix:"x"with|Somestr->float_of_stringstr|None->(matchString.chop_suffixstr~suffix:"%"with|Somestr->float_of_stringstr*.0.01|None->(matchString.chop_suffixstr~suffix:"bp"with|Somestr->of_bp(float_of_stringstr)|None->failwithf"Percent.of_string: must end in x, %%, or bp: %s"str()));;letof_stringstr=letfloatstr=Float_with_finite_only_serialization.t_of_sexp(Sexp.Atomstr)inreally_of_stringstrfloat;;letof_string_allow_nan_and_infstr=really_of_stringstrFloat.of_stringendinclude(Stringable:sigtypetvalof_string:string->tvalto_string:t->stringendwithtypet:=t)include(Sexpable.Stable.Of_stringable.V1(Stringable):Sexpable.Swithtypet:=t)include(Float:Binablewithtypet:=t)includeComparable.Make(structtypenonrect=t[@@derivingcompare,sexp_of](* Previous versions rendered comparable-based containers using float
serialization rather than percent serialization, so when reading
comparable-based containers in we accept either serialization. *)lett_of_sexpsexp=matchFloat.t_of_sexpsexpwith|float->float|exception_->t_of_sexpsexp;;end)endendincludeStable.V1letis_zerot=t=0.letapplytf=t*.fletscaletf=t*.finclude(structincludeFloatletsign=sign_exnend:sigvalzero:tval(*):t->t->tval(+):t->t->tval(-):t->t->tvalabs:t->tvalneg:t->tvalis_nan:t->boolvalis_inf:t->boolvalsign_exn:t->Sign.tincludeComparable.With_zerowithtypet:=tincludeRobustly_comparablewithtypet:=tend)letvalidate=Float.validate_ordinaryletof_string_allow_nan_and_infs=Stringable.of_string_allow_nan_and_infslett_of_sexp_allow_nan_and_infsexp=of_string_allow_nan_and_inf(Sexp.to_stringsexp)