diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-05-20 10:54:35 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-05-21 08:13:38 +0900 |
| commit | fa29bb3bb4801c8ca0256bcd2559ceb159110f68 (patch) | |
| tree | c098da31832f9569f358346612d44b20418d0f44 /src | |
| parent | beaf365dd4758b4d42c0ee72ef18a61fb43e0569 (diff) | |
| download | mruby-fa29bb3bb4801c8ca0256bcd2559ceb159110f68.tar.gz mruby-fa29bb3bb4801c8ca0256bcd2559ceb159110f68.zip | |
fmt_fp.c: remove `fmt` argument from `mrb_float_to_str()`.
With major refactoring to prepare removing `snprintf(3) calls.
Diffstat (limited to 'src')
| -rw-r--r-- | src/fmt_fp.c | 56 | ||||
| -rw-r--r-- | src/numeric.c | 39 |
2 files changed, 31 insertions, 64 deletions
diff --git a/src/fmt_fp.c b/src/fmt_fp.c index 1fcbbd5ac..788b2a70e 100644 --- a/src/fmt_fp.c +++ b/src/fmt_fp.c @@ -1,5 +1,12 @@ #include <mruby.h> -#if !defined(MRB_NO_FLOAT) +#include <string.h> +#ifndef MRB_NO_FLOAT +#ifdef MRB_USE_FLOAT32 +#define FLO_TO_STR_PREC 7 +#else +#define FLO_TO_STR_PREC 15 +#endif + #if defined(MRB_NO_STDIO) || defined(_WIN32) || defined(_WIN64) /* @@ -410,21 +417,6 @@ fmt_core(struct fmt_args *f, const char *fmt, mrb_float flo) } } -mrb_value -mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt) -{ - struct fmt_args f; - mrb_value str = mrb_str_new_capa(mrb, 24); - - f.mrb = mrb; - f.output = strcat_value; - f.opaque = (void*)&str; - if (fmt_core(&f, fmt, mrb_float(flo)) < 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format string"); - } - return str; -} - int mrb_float_to_cstr(mrb_state *mrb, char *buf, size_t len, const char *fmt, mrb_float fval) { @@ -445,19 +437,31 @@ mrb_float_to_cstr(mrb_state *mrb, char *buf, size_t len, const char *fmt, mrb_fl #else /* MRB_NO_STDIO || _WIN32 || _WIN64 */ #include <stdio.h> -mrb_value -mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt) -{ - char buf[25]; - - snprintf(buf, sizeof(buf), fmt, mrb_float(flo)); - return mrb_str_new_cstr(mrb, buf); -} - -MRB_API int +int mrb_float_to_cstr(mrb_state *mrb, char *buf, size_t len, const char *fmt, mrb_float fval) { return snprintf(buf, len, fmt, fval); } + #endif /* MRB_NO_STDIO || _WIN32 || _WIN64 */ + +MRB_API mrb_value +mrb_float_to_str(mrb_state *mrb, mrb_value flo) +{ + char fmt[] = "%." MRB_STRINGIZE(FLO_TO_STR_PREC) "g"; + char buf[25]; + + mrb_float_to_cstr(mrb, buf, sizeof(buf), fmt, mrb_float(flo)); + for (char *p = buf; *p; p++) { + if (*p == '.') goto exit; + if (*p == 'e') { + memmove(p+2, p, strlen(p)+1); + memcpy(p, ".0", 2); + goto exit; + } + } + strcat(buf, ".0"); + exit: + return mrb_str_new_cstr(mrb, buf); +} #endif diff --git a/src/numeric.c b/src/numeric.c index 8aa3459a0..24160fb77 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -25,9 +25,7 @@ #define floor(f) floorf(f) #define ceil(f) ceilf(f) #define fmod(x,y) fmodf(x,y) -#define FLO_TO_STR_PREC 8 #else -#define FLO_TO_STR_PREC 16 #endif #endif @@ -303,49 +301,14 @@ flo_to_s(mrb_state *mrb, mrb_value flt) if (isinf(f)) { str = f < 0 ? mrb_str_new_lit(mrb, "-Infinity") : mrb_str_new_lit(mrb, "Infinity"); - goto exit; } else if (isnan(f)) { str = mrb_str_new_lit(mrb, "NaN"); - goto exit; } else { - char fmt[] = "%." MRB_STRINGIZE(FLO_TO_STR_PREC) "g"; - mrb_int len; - char *begp, *p, *endp; - - str = mrb_float_to_str(mrb, flt, fmt); - - insert_dot_zero: - begp = RSTRING_PTR(str); - len = RSTRING_LEN(str); - for (p = begp, endp = p + len; p < endp; ++p) { - if (*p == '.') { - goto exit; - } - else if (*p == 'e') { - ptrdiff_t e_pos = p - begp; - mrb_str_cat(mrb, str, ".0", 2); - p = RSTRING_PTR(str) + e_pos; - memmove(p + 2, p, len - e_pos); - memcpy(p, ".0", 2); - goto exit; - } - } - - if (FLO_TO_STR_PREC + (begp[0] == '-') <= len) { - --fmt[sizeof(fmt) - 3]; /* %.16g(%.8g) -> %.15g(%.7g) */ - str = mrb_float_to_str(mrb, flt, fmt); - goto insert_dot_zero; - } - else { - mrb_str_cat(mrb, str, ".0", 2); - } - - goto exit; + str = mrb_float_to_str(mrb, flt); } - exit: RSTR_SET_ASCII_FLAG(mrb_str_ptr(str)); return str; } |
