U_CAPI int32_t U_EXPORT2 unum_format( const UNumberFormat* fmt, int32_t number, UChar* result, int32_t resultLength, UFieldPosition *pos, UErrorCode* status) { return unum_formatInt64(fmt, number, result, resultLength, pos, status); }
static Variant doFormat(NumberFormatter *obj, int64_t val) { UErrorCode error = U_ZERO_ERROR; uint32_t len = unum_formatInt64(obj->formatter(), val, nullptr, 0, nullptr, &error); if (error != U_BUFFER_OVERFLOW_ERROR) { obj->setError(error); return false; } error = U_ZERO_ERROR; icu::UnicodeString out; len = unum_formatInt64(obj->formatter(), val, out.getBuffer(len + 1), len + 1, nullptr, &error); NUMFMT_CHECK(obj, error, false); out.releaseBuffer(len); error = U_ZERO_ERROR; String ret(u8(out, error)); NUMFMT_CHECK(obj, error, false); return ret; }
static int32_t u_printf_uinteger_handler(const u_printf_stream_handler *handler, void *context, ULocaleBundle *formatBundle, const u_printf_spec_info *info, const ufmt_args *args) { int64_t num = args[0].int64Value; UNumberFormat *format; UChar result[UPRINTF_BUFFER_SIZE]; int32_t minDigits = -1; int32_t resultLen; UErrorCode status = U_ZERO_ERROR; /* TODO: Fix this once uint64_t can be formatted. */ if (info->fIsShort) num &= UINT16_MAX; else if (!info->fIsLongLong) num &= UINT32_MAX; /* get the formatter */ format = u_locbund_getNumberFormat(formatBundle, UNUM_DECIMAL); /* handle error */ if(format == 0) return 0; /* set the appropriate flags on the formatter */ /* set the minimum integer digits */ if(info->fPrecision != -1) { /* set the minimum # of digits */ minDigits = unum_getAttribute(format, UNUM_MIN_INTEGER_DIGITS); unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, info->fPrecision); } /* To mirror other stdio implementations, we ignore the sign argument */ /* format the number */ resultLen = unum_formatInt64(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status); if (U_FAILURE(status)) { resultLen = 0; } /* restore the number format */ if (minDigits != -1) { unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, minDigits); } return handler->pad_and_justify(context, info, result, resultLen); }
/* HSYS */ static int32_t u_printf_integer_handler(const u_printf_stream_handler *handler, void *context, ULocaleBundle *formatBundle, const u_printf_spec_info *info, const ufmt_args *args) { int64_t num = args[0].int64Value; UNumberFormat *format; UChar result[UPRINTF_BUFFER_SIZE]; UChar prefixBuffer[UPRINTF_BUFFER_SIZE]; int32_t prefixBufferLen = sizeof(prefixBuffer); int32_t minDigits = -1; int32_t resultLen; UErrorCode status = U_ZERO_ERROR; prefixBuffer[0] = 0; /* mask off any necessary bits */ if (info->fIsShort) num = (int16_t)num; else if (!info->fIsLongLong) num = (int32_t)num; /* get the formatter */ format = u_locbund_getNumberFormat(formatBundle, UNUM_DECIMAL); /* handle error */ if(format == 0) return 0; /* set the appropriate flags on the formatter */ /* set the minimum integer digits */ if(info->fPrecision != -1) { /* set the minimum # of digits */ minDigits = unum_getAttribute(format, UNUM_MIN_INTEGER_DIGITS); unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, info->fPrecision); } /* set whether to show the sign */ if(info->fShowSign) { u_printf_set_sign(format, info, prefixBuffer, &prefixBufferLen, &status); } /* format the number */ resultLen = unum_formatInt64(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status); if (U_FAILURE(status)) { resultLen = 0; } /* restore the number format */ if (minDigits != -1) { unum_setAttribute(format, UNUM_MIN_INTEGER_DIGITS, minDigits); } if (info->fShowSign) { /* Reset back to original value regardless of what the error was */ UErrorCode localStatus = U_ZERO_ERROR; u_printf_reset_sign(format, info, prefixBuffer, &prefixBufferLen, &localStatus); } return handler->pad_and_justify(context, info, result, resultLen); }
/** * call-seq: * 23874.localize(:decimal, 'es_ES') => 23.874 */ VALUE rb_numeric_localize(int argc, VALUE *argv, VALUE self) { VALUE style, options; UNumberFormatStyle formatStyle; char *locale = NULL; UNumberFormat *format; UErrorCode status; UChar result[256]; /* arguments */ rb_scan_args(argc, argv, "02", &style, &options); if (style == Qnil) { formatStyle = UNUM_DECIMAL; } else { ID style_ID; Check_Type(style, T_SYMBOL); style_ID = SYM2ID(style); if (style_ID == rb_intern("decimal")) { formatStyle = UNUM_DECIMAL; } else if (style_ID == rb_intern("currency")) { formatStyle = UNUM_CURRENCY; } else if (style_ID == rb_intern("percent")) { formatStyle = UNUM_PERCENT; } else if (style_ID == rb_intern("scientific")) { formatStyle = UNUM_SCIENTIFIC; } else if (style_ID == rb_intern("spellout")) { formatStyle = UNUM_SPELLOUT; } else { rb_raise(rb_eArgError, "unsupported format style %s", rb_id2name(style_ID)); } } if (options != Qnil) { VALUE rb_locale; Check_Type(options, T_HASH); rb_locale = rb_hash_aref(options, ID2SYM(rb_intern("locale"))); if (rb_locale != Qnil) { locale = StringValuePtr(rb_locale); } } /* formatter */ status = U_ZERO_ERROR; format = unum_open(formatStyle, NULL, 0, locale, NULL, &status); RAISE_ON_ERROR(status); /* set format attributes */ if (options != Qnil) { VALUE currency, precision, round_mode, round_increment; switch (formatStyle) { case UNUM_CURRENCY: currency = rb_hash_aref(options, ID2SYM(rb_intern("currency"))); if (currency != Qnil) { UChar *uStr; int32_t uStrLen; uStr = u_strFromRString(currency, &uStrLen); status = U_ZERO_ERROR; unum_setTextAttribute(format, UNUM_CURRENCY_CODE, uStr, uStrLen, &status); RAISE_ON_ERROR(status); } case UNUM_DECIMAL: /* precision */ precision = rb_hash_aref(options, ID2SYM(rb_intern("precision"))); if (precision != Qnil) { Check_Type(precision, T_FIXNUM); status = U_ZERO_ERROR; unum_setAttribute(format, UNUM_FRACTION_DIGITS, NUM2INT(precision)); RAISE_ON_ERROR(status); } round_mode = rb_hash_aref(options, ID2SYM(rb_intern("round_mode"))); if (round_mode != Qnil) { ID round_mode_ID; UNumberFormatRoundingMode rounding_mode; Check_Type(round_mode, T_SYMBOL); round_mode_ID = SYM2ID(round_mode); if (round_mode_ID == rb_intern("ceil")) { rounding_mode = UNUM_ROUND_CEILING; } else if (round_mode_ID == rb_intern("floor")) { rounding_mode = UNUM_ROUND_FLOOR; } else if (round_mode_ID == rb_intern("down")) { rounding_mode = UNUM_ROUND_DOWN; } else if (round_mode_ID == rb_intern("up")) { rounding_mode = UNUM_ROUND_UP; } else if (round_mode_ID == rb_intern("halfeven")) { rounding_mode = UNUM_FOUND_HALFEVEN; } else if (round_mode_ID == rb_intern("halfdown")) { rounding_mode = UNUM_ROUND_HALFDOWN; } else if (round_mode_ID == rb_intern("halfup")) { rounding_mode = UNUM_ROUND_HALFUP; } else { rb_raise(rb_eArgError, "unsupported rounding mode '%s'", rb_id2name(round_mode_ID)); } status = U_ZERO_ERROR; unum_setAttribute(format, UNUM_ROUNDING_MODE, rounding_mode); RAISE_ON_ERROR(status); } round_increment = rb_hash_aref(options, ID2SYM(rb_intern("round_increment"))); if (round_increment != Qnil) { Check_Type(round_increment, T_FLOAT); status = U_ZERO_ERROR; unum_setDoubleAttribute(format, UNUM_ROUNDING_INCREMENT, NUM2DBL(round_increment)); RAISE_ON_ERROR(status); } } } /* format */ status = U_ZERO_ERROR; switch (TYPE(self)) { case T_FIXNUM: unum_format(format, NUM2INT(self), result, 256, NULL, &status); break; case T_FLOAT: unum_formatDouble(format, NUM2DBL(self), result, 256, NULL, &status); break; case T_BIGNUM: unum_formatInt64(format, rb_big2ll(self), result, 256, NULL, &status); break; } RAISE_ON_ERROR(status); /* free resources */ unum_close(format); return u_strToRString(result, -1); }