char * gnm_complex_to_string (gnm_complex const *src, char imunit) { char *re_buffer = NULL; char *im_buffer = NULL; char const *sign = ""; char const *suffix = ""; char *res; char suffix_buffer[2]; const char *fmt = "%.*" GNM_FORMAT_g; static int digits = -1; if (digits == -1) { gnm_float l10 = gnm_log10 (FLT_RADIX); digits = (int)gnm_ceil (GNM_MANT_DIG * l10) + (l10 == (int)l10 ? 0 : 1); } if (src->re != 0 || src->im == 0) { /* We have a real part. */ re_buffer = g_strdup_printf (fmt, digits, src->re); } if (src->im != 0) { /* We have an imaginary part. */ suffix = suffix_buffer; suffix_buffer[0] = imunit; suffix_buffer[1] = 0; if (src->im == 1) { if (re_buffer) sign = "+"; } else if (src->im == -1) { sign = "-"; } else { im_buffer = g_strdup_printf (fmt, digits, src->im); if (re_buffer && *im_buffer != '-' && *im_buffer != '+') sign = (src->im >= 0) ? "+" : "-"; } } res = g_strconcat (re_buffer ? re_buffer : "", sign, im_buffer ? im_buffer : "", suffix, NULL); g_free (re_buffer); g_free (im_buffer); return res; }
void gnm_string_add_number (GString *buf, gnm_float d) { size_t old_len = buf->len; double d2; static int digits; if (digits == 0) { gnm_float l10 = gnm_log10 (FLT_RADIX); digits = (int)gnm_ceil (GNM_MANT_DIG * l10) + (l10 == (int)l10 ? 0 : 1); } g_string_append_printf (buf, "%.*" GNM_FORMAT_g, digits - 1, d); d2 = gnm_strto (buf->str + old_len, NULL); if (d != d2) { g_string_truncate (buf, old_len); g_string_append_printf (buf, "%.*" GNM_FORMAT_g, digits, d); } }
GnmConventions * xlsx_conventions_new (gboolean output) { static struct { char const *gnm_name; gpointer handler; } const xlfn_func_handlers[] = { {"BINOM.INV", xlsx_func_binominv_handler}, {"CHISQ.DIST", xlsx_func_chisqdist_handler}, {"F.DIST", xlsx_func_fdist_handler}, {"NEGBINOM.DIST", xlsx_func_negbinomdist_handler}, {"LOGNORM.DIST", xlsx_func_lognormdist_handler}, {NULL, NULL} }; static struct { char const *gnm_name; gpointer handler; } const xlfn_func_output_handlers[] = { {"R.QBETA", xlsx_func_betainv_output_handler}, {"R.QBINOM", xlsx_func_binominv_output_handler}, {"R.QCHISQ", xlsx_func_chisqinv_output_handler}, {"R.QF", xlsx_func_finv_output_handler}, {"R.QGAMMA", xlsx_func_gammainv_output_handler}, {"R.QLNORM", xlsx_func_lognorminv_output_handler}, {"R.QNORM", xlsx_func_norminv_output_handler}, {"R.QT", xlsx_func_tinv_output_handler}, {"ERF", xlsx_func_erf_output_handler}, {"FLOOR", xlsx_func_floor_output_handler}, {"HYPGEOMDIST", xlsx_func_hypgeomdist_output_handler}, {NULL, NULL} }; static struct { char const *xlsx_name; char const *gnm_name; } const xlfn_func_renames[] = { { "BETA.INV", "BETAINV" }, { "BINOM.DIST", "BINOMDIST" }, /* { "BINOM.INV", "R.QBINOM" }, see handlers */ { "CHISQ.DIST.RT", "CHIDIST" }, { "CHISQ.INV", "R.QCHISQ" }, /* see output handler */ { "CHISQ.INV.RT", "CHIINV" }, { "CHISQ.TEST", "CHITEST" }, { "CONFIDENCE.NORM", "CONFIDENCE" }, { "COVARIANCE.P", "COVAR" }, { "ERF.PRECISE", "ERF" }, { "ERFC.PRECISE", "ERFC" }, { "EXPON.DIST", "EXPONDIST" }, { "F.DIST.RT", "FDIST" }, { "F.INV", "R.QF" }, /* see output handler */ { "F.INV.RT", "FINV" }, { "F.TEST", "FTEST" }, { "GAMMA.DIST", "GAMMADIST" }, { "GAMMA.INV", "GAMMAINV" }, { "HYPGEOM.DIST", "HYPGEOMDIST" }, /* see output handler */ { "LOGNORM.INV", "LOGINV" }, { "MODE.SNGL", "MODE" }, { "NORM.DIST", "NORMDIST" }, { "NORM.INV", "NORMINV" }, { "NORM.S.INV", "NORMSINV" }, { "PERCENTILE.INC", "PERCENTILE" }, { "PERCENTRANK.INC", "PERCENTRANK" }, { "POISSON.DIST", "POISSON" }, { "QUARTILE.INC", "QUARTILE" }, { "RANK.EQ", "RANK" }, { "STDEV.P", "STDEVP" }, { "STDEV.S", "STDEV" }, { "T.TEST", "TTEST" }, { "T.INV.2T", "TINV" }, { "VAR.P", "VARP" }, { "VAR.S", "VAR" }, { "WEIBULL.DIST", "WEIBULL" }, { "Z.TEST", "ZTEST" }, { NULL, NULL } }; GnmConventions *convs = gnm_conventions_new_full ( sizeof (XLSXExprConventions)); XLSXExprConventions *xconv = (XLSXExprConventions *)convs; int i; convs->decimal_sep_dot = TRUE; convs->input.range_ref = rangeref_parse; convs->input.external_wb = xlsx_lookup_external_wb; convs->input.string = xlsx_string_parser; convs->output.cell_ref = xlsx_cellref_as_string; convs->output.range_ref = xlsx_rangeref_as_string; convs->output.string = xlsx_output_string; convs->range_sep_colon = TRUE; convs->sheet_name_sep = '!'; convs->arg_sep = ','; convs->array_col_sep = ','; convs->array_row_sep = ';'; convs->output.translated = FALSE; xconv->extern_id_by_wb = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify) g_object_unref, g_free); xconv->extern_wb_by_id = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref); if (output) { gnm_float l10 = gnm_log10 (FLT_RADIX); convs->output.decimal_digits = (int)gnm_ceil (GNM_MANT_DIG * l10) + (l10 == (int)l10 ? 0 : 1); convs->output.func = xlsx_func_map_out; xconv->xlfn_map = g_hash_table_new (go_ascii_strcase_hash, go_ascii_strcase_equal); for (i = 0; xlfn_func_renames[i].xlsx_name; i++) g_hash_table_insert (xconv->xlfn_map, (gchar *) xlfn_func_renames[i].gnm_name, (gchar *) xlfn_func_renames[i].xlsx_name); xconv->xlfn_handler_map = g_hash_table_new (go_ascii_strcase_hash, go_ascii_strcase_equal); for (i = 0; xlfn_func_output_handlers[i].gnm_name; i++) g_hash_table_insert (xconv->xlfn_handler_map, (gchar *) xlfn_func_output_handlers[i].gnm_name, xlfn_func_output_handlers[i].handler); } else { convs->input.func = xlsx_func_map_in; xconv->xlfn_map = g_hash_table_new (go_ascii_strcase_hash, go_ascii_strcase_equal); for (i = 0; xlfn_func_renames[i].xlsx_name; i++) g_hash_table_insert (xconv->xlfn_map, (gchar *) xlfn_func_renames[i].xlsx_name, (gchar *) xlfn_func_renames[i].gnm_name); xconv->xlfn_handler_map = g_hash_table_new (go_ascii_strcase_hash, go_ascii_strcase_equal); for (i = 0; xlfn_func_handlers[i].gnm_name; i++) g_hash_table_insert (xconv->xlfn_handler_map, (gchar *) xlfn_func_handlers[i].gnm_name, xlfn_func_handlers[i].handler); } return convs; }