NumberFormat / DecimalFormat将某些浮点值视为long而不是double

时间:2010-10-15 01:29:47

标签: c++ icu

NumberFormat / DecimalFormat似乎不会将"#.0"格式(其中#是任意数字)的字符串解析为double。 以下代码说明了这一点:

#include <cstdio>
#include <iostream>
#include <unicode/decimfmt.h>
#include <unicode/numfmt.h>
#include <unicode/unistr.h>
#include <unicode/ustream.h>

int main() {
    UErrorCode status = U_ZERO_ERROR;
    // DecimalFormat doesn't work either
    NumberFormat* f = NumberFormat::createInstance(status);
    f->setGroupingUsed(false);
    f->setParseIntegerOnly(false);

    UnicodeString str("2.0"); // Change to "2.#" for it to work, where # is any non-zero number
    Formattable formattable;
    f->parse(str, formattable, status);
    if (U_FAILURE(status)) {
        printf("ERROR: %s\n", u_errorName(status));
        delete f;
        return 1;
    } else {
        if (formattable.getType() == Formattable::kDouble) {
            printf("kDouble: %f\n", formattable.getDouble());
        } else if ((formattable.getType() == Formattable::kLong)) {
            printf("kLong: %d\n", formattable.getLong());
        } else {
            printf("ERROR: unexpected type: %d\n", formattable.getType());
        }
    }

    str.remove(); // Clear the string
    f->format(2.0f, str);
    std::cout << "formatted: \"" << str << '\"' << std::endl; // Outputs "2"
    delete f;

    return 0;
}

解析"2.0"时,Formattable的类型为2(Formattable::Type::kLong)。解析"2.1"时,Formattable的类型为1(Formattable:Type::kDouble) - 因为它应该适用于两个字符串。

当您尝试将float格式化为UnicodeString时(例如,float 2.0格式化为"2"),也会出现问题。

那么:如果不将其解释为ICU中的整数,我如何解析/格式化任何双数?

1 个答案:

答案 0 :(得分:1)

你可以调用formattable.getDouble(status) - getType返回long的唯一原因是特定值适合long。

至于格式化,如果您在格式化之前调用f->setMinimumFractionDigits(1);,您的代码将获得“2.0”,将最小数字设置为2会得到“2.00”等。

HTH