问题
NumberFormat/DecimalFormat doesn't seem to parse strings with the "#.0"
format (where # is any number) as a double.
The following code illustrates this:
#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;
}
When parsing "2.0"
, the Formattable's type is 2 (Formattable::Type::kLong
). When parsing "2.1"
the Formattable's type is 1 (Formattable:Type::kDouble
) - as it should be for both strings.
Issues also arise when you try to format a float as a UnicodeString (e.g. a float 2.0
gets formatted to "2"
).
So: How can I parse/format any double number without it being interpreted as an integer in ICU?
回答1:
You can call formattable.getDouble(status)
- the only reason getType returns long is that the particular value will fit in a long.
As to format, if you call f->setMinimumFractionDigits(1);
before format, you will get "2.0" with your code, setting the min digits to 2 gives "2.00" etc.
hth
来源:https://stackoverflow.com/questions/3938834/numberformat-decimalformat-treats-certain-floating-point-values-as-longs-instead