diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index 0a7575f..d278c22 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -945,6 +945,21 @@ b + float_to_list(Float, Precision) -> string() + Text representation of a float with given precision + + Float = float() + Precision = int() + + + Returns a string which corresponds to the text + representation of Float with given Precision. If Precision is greater than 250 badarg error is thrown + +> float_to_list(7.1234, 2). +"7.12e+00" + + + erlang:fun_info(Fun) -> [{Item, Info}] Information about a fun diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index f1750a9..68bf6c2 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -2534,6 +2534,29 @@ BIF_RETTYPE float_to_list_1(BIF_ALIST_1) BIF_RET(buf_to_intlist(&hp, fbuf, i, NIL)); } +BIF_RETTYPE float_to_list_2(BIF_ALIST_2) +{ + int i; + Sint precision; + Uint need; + Eterm* hp; + FloatDef f; + char fbuf[512]; + + /* check the arguments */ + if (is_not_float(BIF_ARG_1)) + BIF_ERROR(BIF_P, BADARG); + if (is_not_small(BIF_ARG_2) || unsigned_val(BIF_ARG_2) > 250) + BIF_ERROR(BIF_P, BADARG); + GET_DOUBLE(BIF_ARG_1, f); + precision = unsigned_val(BIF_ARG_2); + if ((i = sys_double_to_chars_precision(f.fd, precision, fbuf)) <= 0) + BIF_ERROR(BIF_P, EXC_INTERNAL_ERROR); + need = i*2; + hp = HAlloc(BIF_P, need); + BIF_RET(buf_to_intlist(&hp, fbuf, i, NIL)); + } + /**********************************************************************/ /* convert a list of ascii integer values e's +'s and -'s to a float */ diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab index 38c9391..ccf972a 100644 --- a/erts/emulator/beam/bif.tab +++ b/erts/emulator/beam/bif.tab @@ -90,6 +90,7 @@ bif 'erl.lang.term':external_size/1 ebif_external_size_1 ubif erlang:float/1 ubif 'erl.lang.number':to_float/1 ebif_to_float_1 float_1 bif erlang:float_to_list/1 +bif erlang:float_to_list/2 bif 'erl.lang.float':to_string/1 ebif_float_to_string_1 float_to_list_1 bif erlang:fun_info/2 bif 'erl.lang.function':info/2 ebif_fun_info_2 diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h index e12aa03..08e816b 100644 --- a/erts/emulator/beam/sys.h +++ b/erts/emulator/beam/sys.h @@ -632,6 +632,7 @@ void fini_getenv_state(GETENV_STATE *); void init_sys_float(void); int sys_chars_to_double(char*, double*); int sys_double_to_chars(double, char*); +int sys_double_to_chars_precision(double, Sint, char*); void sys_get_pid(char *); /* erts_sys_putenv() returns, 0 on success and a value != 0 on failure. */ diff --git a/erts/emulator/sys/unix/sys_float.c b/erts/emulator/sys/unix/sys_float.c index 0285678..e2d2bbf 100644 --- a/erts/emulator/sys/unix/sys_float.c +++ b/erts/emulator/sys/unix/sys_float.c @@ -726,6 +726,22 @@ sys_double_to_chars(double fp, char *buf) return s-buf; /* i.e strlen(buf) */ } +int +sys_double_to_chars_precision(double fp, Sint precision, char *buf) +{ + char *s = buf; + char prec[16]; + (void) sprintf(prec, "%%.%de", (int)precision); + (void) sprintf(buf, prec, fp); + /* Search upto decimal point */ + if (*s == '+' || *s == '-') s++; + while (ISDIGIT(*s)) s++; + if (*s == ',') *s++ = '.'; /* Replace ',' with '.' */ + /* Scan to end of string */ + while (*s) s++; + return s-buf; /* i.e strlen(buf) */ +} + /* Float conversion */ int diff --git a/erts/emulator/sys/vxworks/sys.c b/erts/emulator/sys/vxworks/sys.c index abddc7e..faba284 100644 --- a/erts/emulator/sys/vxworks/sys.c +++ b/erts/emulator/sys/vxworks/sys.c @@ -1595,6 +1595,14 @@ int sys_double_to_chars(double fp, char *buf) return strlen(buf); } +int +sys_double_to_chars_precision(double fp, Sint precision, char *buf) +{ + char prec[16]; + (void) sprintf(prec, "%%.%de", (int)precision); + (void) sprintf(buf, prec, fp); + return strlen(buf); +} /* Floating point exceptions */ diff --git a/erts/emulator/sys/win32/sys_float.c b/erts/emulator/sys/win32/sys_float.c index 9e67ca7..4201fd4 100644 --- a/erts/emulator/sys/win32/sys_float.c +++ b/erts/emulator/sys/win32/sys_float.c @@ -130,6 +130,22 @@ sys_double_to_chars(double fp, char *buf) } int +sys_double_to_chars_precision(double fp, Sint precision, char *buf) +{ + char *s = buf; + char prec[16]; + (void) sprintf(prec, "%%.%de", (int)precision); + (void) sprintf(buf, prec, fp); + /* Search upto decimal point */ + if (*s == '+' || *s == '-') s++; + while (ISDIGIT(*s)) s++; + if (*s == ',') *s++ = '.'; /* Replace ',' with '.' */ + /* Scan to end of string */ + while (*s) s++; + return s-buf; /* i.e strlen(buf) */ +} + +int matherr(struct _exception *exc) { erl_fp_exception = 1;
Returns a string which corresponds to the text + representation of Float with given Precision. If Precision is greater than 250 badarg error is thrown
+> float_to_list(7.1234, 2). +"7.12e+00"