ICU-10952 Add JAVA ScientificNumberFormatter class.
X-SVN-Rev: 36749
This commit is contained in:
parent
9dafb86e93
commit
83db643252
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -274,6 +274,7 @@ icu4j/main/classes/core/.settings/edu.umd.cs.findbugs.core.prefs -text
|
||||
icu4j/main/classes/core/.settings/org.eclipse.core.resources.prefs -text
|
||||
icu4j/main/classes/core/.settings/org.eclipse.jdt.core.prefs -text
|
||||
icu4j/main/classes/core/manifest.stub -text
|
||||
icu4j/main/classes/core/src/com/ibm/icu/text/ScientificNumberFormatter.java -text
|
||||
icu4j/main/classes/currdata/.externalToolBuilders/copy-data-currdata.launch -text
|
||||
icu4j/main/classes/currdata/.settings/org.eclipse.core.resources.prefs -text
|
||||
icu4j/main/classes/currdata/.settings/org.eclipse.jdt.core.prefs -text
|
||||
@ -334,6 +335,7 @@ icu4j/main/tests/core/manifest.stub -text
|
||||
icu4j/main/tests/core/src/com/ibm/icu/dev/data/rbbi/english.dict -text
|
||||
icu4j/main/tests/core/src/com/ibm/icu/dev/data/resources/testmessages.properties -text
|
||||
icu4j/main/tests/core/src/com/ibm/icu/dev/data/thai6.ucs -text
|
||||
icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/ScientificNumberFormatterTest.java -text
|
||||
icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.impl.OlsonTimeZone.dat -text
|
||||
icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.impl.TimeZoneAdapter.dat -text
|
||||
icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.math.BigDecimal.dat -text
|
||||
|
@ -1782,7 +1782,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
boolean negativeExponent = exponent < 0;
|
||||
if (negativeExponent) {
|
||||
exponent = -exponent;
|
||||
result.append(symbols.getMinusSign());
|
||||
result.append(symbols.getMinusString());
|
||||
// [Spark/CDL] If exponent has sign, then add an exponent sign
|
||||
// attribute.
|
||||
if (parseAttr) {
|
||||
@ -1790,7 +1790,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
addAttribute(Field.EXPONENT_SIGN, result.length() - 1, result.length());
|
||||
}
|
||||
} else if (exponentSignAlwaysShown) {
|
||||
result.append(symbols.getPlusSign());
|
||||
result.append(symbols.getPlusString());
|
||||
// [Spark/CDL] Add an plus sign attribute.
|
||||
if (parseAttr) {
|
||||
// Length of exponent sign is 1.
|
||||
|
@ -7,11 +7,6 @@
|
||||
package com.ibm.icu.text;
|
||||
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.text.AttributedCharacterIterator.Attribute;
|
||||
import java.text.CharacterIterator;
|
||||
import java.util.Map;
|
||||
|
||||
import com.ibm.icu.lang.UCharacter;
|
||||
|
||||
/**
|
||||
* A helper class for formatting in user-friendly scientific notation.
|
||||
@ -38,13 +33,6 @@ import com.ibm.icu.lang.UCharacter;
|
||||
*/
|
||||
public final class ScientificFormatHelper {
|
||||
|
||||
private static final char[] SUPERSCRIPT_DIGITS = {
|
||||
0x2070, 0xB9, 0xB2, 0xB3, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078, 0x2079
|
||||
};
|
||||
|
||||
private static final char SUPERSCRIPT_PLUS_SIGN = 0x207A;
|
||||
private static final char SUPERSCRIPT_MINUS_SIGN = 0x207B;
|
||||
|
||||
private final String preExponent;
|
||||
|
||||
private ScientificFormatHelper(String preExponent) {
|
||||
@ -58,15 +46,7 @@ public final class ScientificFormatHelper {
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public static ScientificFormatHelper getInstance(DecimalFormatSymbols dfs) {
|
||||
StringBuilder preExponent = new StringBuilder();
|
||||
preExponent.append(getMultiplicationSymbol(dfs));
|
||||
char[] digits = dfs.getDigits();
|
||||
preExponent.append(digits[1]).append(digits[0]);
|
||||
return new ScientificFormatHelper(preExponent.toString());
|
||||
}
|
||||
|
||||
private static String getMultiplicationSymbol(DecimalFormatSymbols dfs) {
|
||||
return dfs.getExponentMultiplicationSign();
|
||||
return new ScientificFormatHelper(ScientificNumberFormatter.getPreExponent(dfs));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,61 +63,10 @@ public final class ScientificFormatHelper {
|
||||
AttributedCharacterIterator iterator,
|
||||
CharSequence beginMarkup,
|
||||
CharSequence endMarkup) {
|
||||
int copyFromOffset = 0;
|
||||
StringBuilder result = new StringBuilder();
|
||||
boolean exponentSymbolFieldPresent = false;
|
||||
boolean exponentFieldPresent = false;
|
||||
for (
|
||||
iterator.first();
|
||||
iterator.current() != CharacterIterator.DONE;
|
||||
) {
|
||||
Map<Attribute, Object> attributeSet = iterator.getAttributes();
|
||||
if (attributeSet.containsKey(NumberFormat.Field.EXPONENT_SYMBOL)) {
|
||||
exponentSymbolFieldPresent = true;
|
||||
append(
|
||||
return format(
|
||||
iterator,
|
||||
copyFromOffset,
|
||||
iterator.getRunStart(NumberFormat.Field.EXPONENT_SYMBOL),
|
||||
result);
|
||||
copyFromOffset = iterator.getRunLimit(NumberFormat.Field.EXPONENT_SYMBOL);
|
||||
iterator.setIndex(copyFromOffset);
|
||||
result.append(preExponent);
|
||||
result.append(beginMarkup);
|
||||
} else if (attributeSet.containsKey(NumberFormat.Field.EXPONENT)) {
|
||||
exponentFieldPresent = true;
|
||||
int limit = iterator.getRunLimit(NumberFormat.Field.EXPONENT);
|
||||
append(
|
||||
iterator,
|
||||
copyFromOffset,
|
||||
limit,
|
||||
result);
|
||||
copyFromOffset = limit;
|
||||
iterator.setIndex(copyFromOffset);
|
||||
result.append(endMarkup);
|
||||
} else {
|
||||
iterator.next();
|
||||
}
|
||||
}
|
||||
if (!exponentSymbolFieldPresent || !exponentFieldPresent) {
|
||||
throw new IllegalArgumentException("Must start with standard e notation.");
|
||||
}
|
||||
append(iterator, copyFromOffset, iterator.getEndIndex(), result);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
|
||||
private static void append(
|
||||
AttributedCharacterIterator iterator,
|
||||
int start,
|
||||
int limit,
|
||||
StringBuilder result) {
|
||||
int oldIndex = iterator.getIndex();
|
||||
iterator.setIndex(start);
|
||||
for (int i = start; i < limit; i++) {
|
||||
result.append(iterator.current());
|
||||
iterator.next();
|
||||
}
|
||||
iterator.setIndex(oldIndex);
|
||||
new ScientificNumberFormatter.MarkupStyle(
|
||||
beginMarkup.toString(), endMarkup.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -150,99 +79,11 @@ public final class ScientificFormatHelper {
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public String toSuperscriptExponentDigits(AttributedCharacterIterator iterator) {
|
||||
int copyFromOffset = 0;
|
||||
StringBuilder result = new StringBuilder();
|
||||
boolean exponentSymbolFieldPresent = false;
|
||||
boolean exponentFieldPresent = false;
|
||||
for (
|
||||
iterator.first();
|
||||
iterator.current() != CharacterIterator.DONE;
|
||||
) {
|
||||
Map<Attribute, Object> attributeSet = iterator.getAttributes();
|
||||
if (attributeSet.containsKey(NumberFormat.Field.EXPONENT_SYMBOL)) {
|
||||
exponentSymbolFieldPresent = true;
|
||||
append(
|
||||
iterator,
|
||||
copyFromOffset,
|
||||
iterator.getRunStart(NumberFormat.Field.EXPONENT_SYMBOL),
|
||||
result);
|
||||
copyFromOffset = iterator.getRunLimit(NumberFormat.Field.EXPONENT_SYMBOL);
|
||||
iterator.setIndex(copyFromOffset);
|
||||
result.append(preExponent);
|
||||
} else if (attributeSet.containsKey(NumberFormat.Field.EXPONENT_SIGN)) {
|
||||
int start = iterator.getRunStart(NumberFormat.Field.EXPONENT_SIGN);
|
||||
int limit = iterator.getRunLimit(NumberFormat.Field.EXPONENT_SIGN);
|
||||
int aChar = char32AtAndAdvance(iterator);
|
||||
if (DecimalFormat.minusSigns.contains(aChar)) {
|
||||
append(
|
||||
iterator,
|
||||
copyFromOffset,
|
||||
start,
|
||||
result);
|
||||
result.append(SUPERSCRIPT_MINUS_SIGN);
|
||||
} else if (DecimalFormat.plusSigns.contains(aChar)) {
|
||||
append(
|
||||
iterator,
|
||||
copyFromOffset,
|
||||
start,
|
||||
result);
|
||||
result.append(SUPERSCRIPT_PLUS_SIGN);
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
copyFromOffset = limit;
|
||||
iterator.setIndex(copyFromOffset);
|
||||
} else if (attributeSet.containsKey(NumberFormat.Field.EXPONENT)) {
|
||||
exponentFieldPresent = true;
|
||||
int start = iterator.getRunStart(NumberFormat.Field.EXPONENT);
|
||||
int limit = iterator.getRunLimit(NumberFormat.Field.EXPONENT);
|
||||
append(
|
||||
iterator,
|
||||
copyFromOffset,
|
||||
start,
|
||||
result);
|
||||
copyAsSuperscript(iterator, start, limit, result);
|
||||
copyFromOffset = limit;
|
||||
iterator.setIndex(copyFromOffset);
|
||||
} else {
|
||||
iterator.next();
|
||||
}
|
||||
}
|
||||
if (!exponentSymbolFieldPresent || !exponentFieldPresent) {
|
||||
throw new IllegalArgumentException("Must start with standard e notation.");
|
||||
}
|
||||
append(iterator, copyFromOffset, iterator.getEndIndex(), result);
|
||||
return result.toString();
|
||||
return format(iterator, ScientificNumberFormatter.SUPER_SCRIPT);
|
||||
}
|
||||
|
||||
private static void copyAsSuperscript(
|
||||
AttributedCharacterIterator iterator, int start, int limit, StringBuilder result) {
|
||||
int oldIndex = iterator.getIndex();
|
||||
iterator.setIndex(start);
|
||||
while (iterator.getIndex() < limit) {
|
||||
int aChar = char32AtAndAdvance(iterator);
|
||||
int digit = UCharacter.digit(aChar);
|
||||
if (digit < 0) {
|
||||
throw new IllegalArgumentException();
|
||||
private String format(
|
||||
AttributedCharacterIterator iterator, ScientificNumberFormatter.Style option) {
|
||||
return option.format(iterator, preExponent);
|
||||
}
|
||||
result.append(SUPERSCRIPT_DIGITS[digit]);
|
||||
}
|
||||
iterator.setIndex(oldIndex);
|
||||
}
|
||||
|
||||
private static int char32AtAndAdvance(AttributedCharacterIterator iterator) {
|
||||
char c1 = iterator.current();
|
||||
iterator.next();
|
||||
if (UCharacter.isHighSurrogate(c1)) {
|
||||
char c2 = iterator.current();
|
||||
if (c2 != CharacterIterator.DONE) {
|
||||
if (UCharacter.isLowSurrogate(c2)) {
|
||||
iterator.next();
|
||||
return UCharacter.toCodePoint(c1, c2);
|
||||
}
|
||||
}
|
||||
}
|
||||
return c1;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,342 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2014, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.text;
|
||||
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.text.CharacterIterator;
|
||||
import java.text.AttributedCharacterIterator.Attribute;
|
||||
import java.util.Map;
|
||||
|
||||
import com.ibm.icu.lang.UCharacter;
|
||||
import com.ibm.icu.util.ULocale;
|
||||
|
||||
/**
|
||||
*A formatter that formats numbers in user-friendly scientific notation.
|
||||
*
|
||||
* ScientificNumberFormatter instances are immutable and thread-safe.
|
||||
*
|
||||
* Sample code:
|
||||
* <pre>
|
||||
* ULocale en = new ULocale("en");
|
||||
* ScientificNumberFormatter fmt = ScientificNumberFormatter.getMarkupInstance(
|
||||
* en, "<sup>", "</sup>");
|
||||
* <pre>
|
||||
* // Output: "1.23456×10<sup>-78</sup>"
|
||||
* System.out.println(fmt.format(1.23456e-78));
|
||||
* </pre>
|
||||
*
|
||||
* @draft ICU 55
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*
|
||||
*/
|
||||
public final class ScientificNumberFormatter {
|
||||
|
||||
private final String preExponent;
|
||||
private final DecimalFormat fmt;
|
||||
private final Style style;
|
||||
|
||||
/**
|
||||
* Gets a ScientificNumberFormatter instance that uses
|
||||
* superscript characters for exponents for this locale.
|
||||
* @param locale The locale
|
||||
* @return The ScientificNumberFormatter instance.
|
||||
*
|
||||
* @draft ICU 55
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public static ScientificNumberFormatter getSuperscriptInstance(ULocale locale) {
|
||||
return getInstanceForLocale(locale, SUPER_SCRIPT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a ScientificNumberFormatter instance that uses
|
||||
* superscript characters for exponents.
|
||||
* @param df The DecimalFormat must be configured for scientific
|
||||
* notation. Caller may safely change df after this call as this method
|
||||
* clones it when creating the ScientificNumberFormatter.
|
||||
* @return the ScientificNumberFormatter instance.
|
||||
*
|
||||
* @draft ICU 55
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public static ScientificNumberFormatter getSuperscriptInstance(
|
||||
DecimalFormat df) {
|
||||
return getInstance(df, SUPER_SCRIPT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a ScientificNumberFormatter instance that uses
|
||||
* markup for exponents for this locale.
|
||||
* @param locale The locale
|
||||
* @param beginMarkup the markup to start superscript e.g {@code <sup>}
|
||||
* @param endMarkup the markup to end superscript e.g {@code </sup>}
|
||||
* @return The ScientificNumberFormatter instance.
|
||||
*
|
||||
* @draft ICU 55
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public static ScientificNumberFormatter getMarkupInstance(
|
||||
ULocale locale,
|
||||
String beginMarkup,
|
||||
String endMarkup) {
|
||||
return getInstanceForLocale(
|
||||
locale, new MarkupStyle(beginMarkup, endMarkup));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a ScientificNumberFormatter instance that uses
|
||||
* markup for exponents.
|
||||
* @param df The DecimalFormat must be configured for scientific
|
||||
* notation. Caller may safely change df after this call as this method
|
||||
* clones it when creating the ScientificNumberFormatter.
|
||||
* @param beginMarkup the markup to start superscript e.g {@code <sup>}
|
||||
* @param endMarkup the markup to end superscript e.g {@code </sup>}
|
||||
* @return The ScientificNumberFormatter instance.
|
||||
*
|
||||
* @draft ICU 55
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public static ScientificNumberFormatter getMarkupInstance(
|
||||
DecimalFormat df,
|
||||
String beginMarkup,
|
||||
String endMarkup) {
|
||||
return getInstance(
|
||||
df, new MarkupStyle(beginMarkup, endMarkup));
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a number
|
||||
* @param number Can be a double, int, Number or
|
||||
* anything that DecimalFormat#format(Object) accepts.
|
||||
* @return the formatted string.
|
||||
*
|
||||
* @draft ICU 55
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public String format(Object number) {
|
||||
synchronized (fmt) {
|
||||
return style.format(
|
||||
fmt.formatToCharacterIterator(number),
|
||||
preExponent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A style type for ScientificNumberFormatter. All Style instances are immutable
|
||||
* and thread-safe.
|
||||
* TODO: Make private once ScientificFormatHelper is deleted.
|
||||
*/
|
||||
static abstract class Style {
|
||||
abstract String format(
|
||||
AttributedCharacterIterator iterator,
|
||||
String preExponent); // '* 10^'
|
||||
|
||||
static void append(
|
||||
AttributedCharacterIterator iterator,
|
||||
int start,
|
||||
int limit,
|
||||
StringBuilder result) {
|
||||
int oldIndex = iterator.getIndex();
|
||||
iterator.setIndex(start);
|
||||
for (int i = start; i < limit; i++) {
|
||||
result.append(iterator.current());
|
||||
iterator.next();
|
||||
}
|
||||
iterator.setIndex(oldIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: make private
|
||||
static class MarkupStyle extends Style {
|
||||
|
||||
private final String beginMarkup;
|
||||
private final String endMarkup;
|
||||
|
||||
MarkupStyle(String beginMarkup, String endMarkup) {
|
||||
this.beginMarkup = beginMarkup;
|
||||
this.endMarkup = endMarkup;
|
||||
}
|
||||
|
||||
@Override
|
||||
String format(
|
||||
AttributedCharacterIterator iterator,
|
||||
String preExponent) {
|
||||
int copyFromOffset = 0;
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (
|
||||
iterator.first();
|
||||
iterator.current() != CharacterIterator.DONE;
|
||||
) {
|
||||
Map<Attribute, Object> attributeSet = iterator.getAttributes();
|
||||
if (attributeSet.containsKey(NumberFormat.Field.EXPONENT_SYMBOL)) {
|
||||
append(
|
||||
iterator,
|
||||
copyFromOffset,
|
||||
iterator.getRunStart(NumberFormat.Field.EXPONENT_SYMBOL),
|
||||
result);
|
||||
copyFromOffset = iterator.getRunLimit(NumberFormat.Field.EXPONENT_SYMBOL);
|
||||
iterator.setIndex(copyFromOffset);
|
||||
result.append(preExponent);
|
||||
result.append(beginMarkup);
|
||||
} else if (attributeSet.containsKey(NumberFormat.Field.EXPONENT)) {
|
||||
int limit = iterator.getRunLimit(NumberFormat.Field.EXPONENT);
|
||||
append(
|
||||
iterator,
|
||||
copyFromOffset,
|
||||
limit,
|
||||
result);
|
||||
copyFromOffset = limit;
|
||||
iterator.setIndex(copyFromOffset);
|
||||
result.append(endMarkup);
|
||||
} else {
|
||||
iterator.next();
|
||||
}
|
||||
}
|
||||
append(iterator, copyFromOffset, iterator.getEndIndex(), result);
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Make private
|
||||
static class SuperscriptStyle extends Style {
|
||||
|
||||
private static final char[] SUPERSCRIPT_DIGITS = {
|
||||
0x2070, 0xB9, 0xB2, 0xB3, 0x2074, 0x2075, 0x2076, 0x2077, 0x2078, 0x2079
|
||||
};
|
||||
|
||||
private static final char SUPERSCRIPT_PLUS_SIGN = 0x207A;
|
||||
private static final char SUPERSCRIPT_MINUS_SIGN = 0x207B;
|
||||
|
||||
@Override
|
||||
String format(
|
||||
AttributedCharacterIterator iterator,
|
||||
String preExponent) {
|
||||
int copyFromOffset = 0;
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (
|
||||
iterator.first();
|
||||
iterator.current() != CharacterIterator.DONE;
|
||||
) {
|
||||
Map<Attribute, Object> attributeSet = iterator.getAttributes();
|
||||
if (attributeSet.containsKey(NumberFormat.Field.EXPONENT_SYMBOL)) {
|
||||
append(
|
||||
iterator,
|
||||
copyFromOffset,
|
||||
iterator.getRunStart(NumberFormat.Field.EXPONENT_SYMBOL),
|
||||
result);
|
||||
copyFromOffset = iterator.getRunLimit(NumberFormat.Field.EXPONENT_SYMBOL);
|
||||
iterator.setIndex(copyFromOffset);
|
||||
result.append(preExponent);
|
||||
} else if (attributeSet.containsKey(NumberFormat.Field.EXPONENT_SIGN)) {
|
||||
int start = iterator.getRunStart(NumberFormat.Field.EXPONENT_SIGN);
|
||||
int limit = iterator.getRunLimit(NumberFormat.Field.EXPONENT_SIGN);
|
||||
int aChar = char32AtAndAdvance(iterator);
|
||||
if (DecimalFormat.minusSigns.contains(aChar)) {
|
||||
append(
|
||||
iterator,
|
||||
copyFromOffset,
|
||||
start,
|
||||
result);
|
||||
result.append(SUPERSCRIPT_MINUS_SIGN);
|
||||
} else if (DecimalFormat.plusSigns.contains(aChar)) {
|
||||
append(
|
||||
iterator,
|
||||
copyFromOffset,
|
||||
start,
|
||||
result);
|
||||
result.append(SUPERSCRIPT_PLUS_SIGN);
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
copyFromOffset = limit;
|
||||
iterator.setIndex(copyFromOffset);
|
||||
} else if (attributeSet.containsKey(NumberFormat.Field.EXPONENT)) {
|
||||
int start = iterator.getRunStart(NumberFormat.Field.EXPONENT);
|
||||
int limit = iterator.getRunLimit(NumberFormat.Field.EXPONENT);
|
||||
append(
|
||||
iterator,
|
||||
copyFromOffset,
|
||||
start,
|
||||
result);
|
||||
copyAsSuperscript(iterator, start, limit, result);
|
||||
copyFromOffset = limit;
|
||||
iterator.setIndex(copyFromOffset);
|
||||
} else {
|
||||
iterator.next();
|
||||
}
|
||||
}
|
||||
append(iterator, copyFromOffset, iterator.getEndIndex(), result);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private static void copyAsSuperscript(
|
||||
AttributedCharacterIterator iterator, int start, int limit, StringBuilder result) {
|
||||
int oldIndex = iterator.getIndex();
|
||||
iterator.setIndex(start);
|
||||
while (iterator.getIndex() < limit) {
|
||||
int aChar = char32AtAndAdvance(iterator);
|
||||
int digit = UCharacter.digit(aChar);
|
||||
if (digit < 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
result.append(SUPERSCRIPT_DIGITS[digit]);
|
||||
}
|
||||
iterator.setIndex(oldIndex);
|
||||
}
|
||||
|
||||
private static int char32AtAndAdvance(AttributedCharacterIterator iterator) {
|
||||
char c1 = iterator.current();
|
||||
char c2 = iterator.next();
|
||||
if (UCharacter.isHighSurrogate(c1)) {
|
||||
// If c2 is DONE, it will fail the low surrogate test and we
|
||||
// skip this block.
|
||||
if (UCharacter.isLowSurrogate(c2)) {
|
||||
iterator.next();
|
||||
return UCharacter.toCodePoint(c1, c2);
|
||||
}
|
||||
}
|
||||
return c1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static String getPreExponent(DecimalFormatSymbols dfs) {
|
||||
StringBuilder preExponent = new StringBuilder();
|
||||
preExponent.append(dfs.getExponentMultiplicationSign());
|
||||
char[] digits = dfs.getDigits();
|
||||
preExponent.append(digits[1]).append(digits[0]);
|
||||
return preExponent.toString();
|
||||
}
|
||||
|
||||
static ScientificNumberFormatter getInstance(
|
||||
DecimalFormat decimalFormat, Style style) {
|
||||
DecimalFormatSymbols dfs = decimalFormat.getDecimalFormatSymbols();
|
||||
return new ScientificNumberFormatter(
|
||||
(DecimalFormat) decimalFormat.clone(), getPreExponent(dfs), style);
|
||||
}
|
||||
|
||||
static ScientificNumberFormatter getInstanceForLocale(
|
||||
ULocale locale, Style style) {
|
||||
DecimalFormat decimalFormat =
|
||||
(DecimalFormat) DecimalFormat.getScientificInstance(locale);
|
||||
return new ScientificNumberFormatter(
|
||||
decimalFormat,
|
||||
getPreExponent(decimalFormat.getDecimalFormatSymbols()),
|
||||
style);
|
||||
}
|
||||
|
||||
static final Style SUPER_SCRIPT = new SuperscriptStyle();
|
||||
|
||||
private ScientificNumberFormatter(
|
||||
DecimalFormat decimalFormat, String preExponent, Style style) {
|
||||
this.fmt = decimalFormat;
|
||||
this.preExponent = preExponent;
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -69,12 +69,7 @@ public class ScientificFormatHelperTest extends TestFmwk {
|
||||
AttributedCharacterIterator iterator = decfmt.formatToCharacterIterator(123456.0);
|
||||
ScientificFormatHelper helper = ScientificFormatHelper.getInstance(
|
||||
decfmt.getDecimalFormatSymbols());
|
||||
try {
|
||||
helper.insertMarkup(iterator, "<sup>", "</sup>");
|
||||
fail("expected illegal argument exception");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
// do nothing
|
||||
}
|
||||
assertEquals("", "123,456", helper.insertMarkup(iterator, "<sup>", "</sup>"));
|
||||
}
|
||||
|
||||
public void TestFixedDecimalSuperscript() {
|
||||
@ -83,11 +78,6 @@ public class ScientificFormatHelperTest extends TestFmwk {
|
||||
AttributedCharacterIterator iterator = decfmt.formatToCharacterIterator(123456.0);
|
||||
ScientificFormatHelper helper = ScientificFormatHelper.getInstance(
|
||||
decfmt.getDecimalFormatSymbols());
|
||||
try {
|
||||
helper.toSuperscriptExponentDigits(iterator);
|
||||
fail("expected illegal argument exception");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
// do nothing
|
||||
}
|
||||
assertEquals("", "123,456", helper.toSuperscriptExponentDigits(iterator));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2014, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.test.format;
|
||||
|
||||
import com.ibm.icu.dev.test.TestFmwk;
|
||||
import com.ibm.icu.text.DecimalFormat;
|
||||
import com.ibm.icu.text.NumberFormat;
|
||||
import com.ibm.icu.text.ScientificNumberFormatter;
|
||||
import com.ibm.icu.util.ULocale;
|
||||
|
||||
/**
|
||||
* @author rocketman
|
||||
*
|
||||
*/
|
||||
public class ScientificNumberFormatterTest extends TestFmwk {
|
||||
public static void main(String[] args) throws Exception {
|
||||
new ScientificNumberFormatterTest().run(args);
|
||||
}
|
||||
|
||||
public void TestBasic() {
|
||||
ScientificNumberFormatter markup = ScientificNumberFormatter.getMarkupInstance(
|
||||
ULocale.ENGLISH, "<sup>", "</sup>");
|
||||
ScientificNumberFormatter superscript = ScientificNumberFormatter.getSuperscriptInstance(ULocale.ENGLISH);
|
||||
assertEquals(
|
||||
"toMarkupExponentDigits",
|
||||
"1.23456×10<sup>-78</sup>",
|
||||
markup.format(1.23456e-78));
|
||||
assertEquals(
|
||||
"toSuperscriptExponentDigits",
|
||||
"1.23456×10⁻⁷⁸",
|
||||
superscript.format(1.23456e-78));
|
||||
}
|
||||
|
||||
|
||||
public void TestFarsi() {
|
||||
ScientificNumberFormatter fmt = ScientificNumberFormatter.getMarkupInstance(
|
||||
new ULocale("fa"), "<sup>", "</sup>");
|
||||
assertEquals(
|
||||
"",
|
||||
"۱٫۲۳۴۵۶×۱۰<sup>−۷۸</sup>",
|
||||
fmt.format(1.23456e-78));
|
||||
}
|
||||
|
||||
|
||||
public void TestPlusSignInExponentMarkup() {
|
||||
DecimalFormat decfmt = (DecimalFormat) NumberFormat.getScientificInstance(ULocale.ENGLISH);
|
||||
decfmt.applyPattern("0.00E+0");
|
||||
ScientificNumberFormatter fmt = ScientificNumberFormatter.getMarkupInstance(
|
||||
decfmt, "<sup>", "</sup>");
|
||||
|
||||
assertEquals(
|
||||
"",
|
||||
"6.02×10<sup>+23</sup>",
|
||||
fmt.format(6.02e23));
|
||||
}
|
||||
|
||||
|
||||
public void TestPlusSignInExponentSuperscript() {
|
||||
DecimalFormat decfmt = (DecimalFormat) NumberFormat.getScientificInstance(ULocale.ENGLISH);
|
||||
decfmt.applyPattern("0.00E+0");
|
||||
ScientificNumberFormatter fmt = ScientificNumberFormatter.getSuperscriptInstance(
|
||||
decfmt);
|
||||
assertEquals(
|
||||
"",
|
||||
"6.02×10⁺²³",
|
||||
fmt.format(6.02e23));
|
||||
}
|
||||
|
||||
public void TestFixedDecimalMarkup() {
|
||||
DecimalFormat decfmt = (DecimalFormat) NumberFormat.getInstance(ULocale.ENGLISH);
|
||||
ScientificNumberFormatter fmt = ScientificNumberFormatter.getMarkupInstance(
|
||||
decfmt, "<sup>", "</sup>");
|
||||
assertEquals(
|
||||
"",
|
||||
"123,456",
|
||||
fmt.format(123456.0));
|
||||
}
|
||||
|
||||
public void TestFixedDecimalSuperscript() {
|
||||
DecimalFormat decfmt = (DecimalFormat) NumberFormat.getInstance(ULocale.ENGLISH);
|
||||
ScientificNumberFormatter fmt = ScientificNumberFormatter.getSuperscriptInstance(decfmt);
|
||||
assertEquals(
|
||||
"",
|
||||
"123,456",
|
||||
fmt.format(123456.0));
|
||||
}
|
||||
}
|
@ -60,6 +60,7 @@ public class TestAll extends TestGroup {
|
||||
"NumberRegression",
|
||||
"NumberFormatRegressionTest",
|
||||
"ScientificFormatHelperTest",
|
||||
"ScientificNumberFormatterTest",
|
||||
"IntlTestDecimalFormatAPI",
|
||||
"IntlTestDecimalFormatAPIC",
|
||||
"IntlTestDecimalFormatSymbols",
|
||||
|
Loading…
Reference in New Issue
Block a user