choiceformat.java
来自「《移动Agent技术》一书的所有章节源代码。」· Java 代码 · 共 446 行 · 第 1/2 页
JAVA
446 行
* @param formats are the formats you want to use for each limit.
* They can be either Format objects or Strings.
* When formatting with object Y,
* if the object is a NumberFormat, then ((NumberFormat) Y).format(X)
* is called. Otherwise Y.toString() is called.
*/
public void setChoices(double[] limits, String formats[]) {
choiceLimits = limits;
choiceFormats = formats;
}
/**
* Get the limits passed in the constructor.
* @return the limits.
*/
public double[] getLimits() {
return choiceLimits;
}
/**
* Get the formats passed in the constructor.
* @return the formats.
*/
public Object[] getFormats() {
return choiceFormats;
}
// Overrides
/**
* Specialization of format. This method really calls
* <code>format(double, StringBuffer, FieldPosition)</code>
* thus the range of longs that are supported is only equal to
* the range that can be stored by double. This will never be
* a practical limitation.
*/
public StringBuffer format(long number, StringBuffer toAppendTo,
FieldPosition status) {
return format((double)number, toAppendTo, status);
}
public StringBuffer format(double number, StringBuffer toAppendTo,
FieldPosition status) {
// find the number
int i;
for (i = 0; i < choiceLimits.length; ++i) {
if (!(number >= choiceLimits[i])) {
// same as number < choiceLimits, except catchs NaN
break;
}
}
--i;
if (i < 0) i = 0;
// return either a formatted number, or a string
return toAppendTo.append(choiceFormats[i]);
}
public Number parse(String text, ParsePosition status) {
// find the best number (defined as the one with the longest parse)
int start = status.index;
int furthest = start;
double bestNumber = Double.NaN;
double tempNumber = 0.0;
for (int i = 0; i < choiceFormats.length; ++i) {
String tempString = choiceFormats[i];
if (text.regionMatches(start, tempString, 0, tempString.length())) {
status.index = tempString.length();
tempNumber = choiceLimits[i];
if (status.index > furthest) {
furthest = status.index;
bestNumber = tempNumber;
if (furthest == text.length()) break;
}
}
}
status.index = furthest;
return new Double(bestNumber);
}
/**
* Finds the least double greater than d.
* If NaN, returns same value.
* <p>Used to make half-open intervals.
* @see #previousDouble
*/
public static final double nextDouble (double d) {
return nextDouble(d,true);
}
/**
* Finds the greatest double less than d.
* If NaN, returns same value.
* @see #nextDouble
*/
public static final double previousDouble (double d) {
return nextDouble(d,false);
}
/**
* Overrides Cloneable
*/
public Object clone()
{
ChoiceFormat other = (ChoiceFormat) super.clone();
// for primitives or immutables, shallow clone is enough
other.choiceLimits = (double[]) choiceLimits.clone();
other.choiceFormats = (String[]) choiceFormats.clone();
return other;
}
/**
* Generates a hash code for the message format object.
*/
public int hashCode() {
int result = choiceLimits.length;
if (choiceFormats.length > 0) {
// enough for reasonable distribution
result ^= choiceFormats[choiceFormats.length-1].hashCode();
}
return result;
}
/**
* Equality comparision between two
*/
public boolean equals(Object obj) {
if (this == obj) // quick check
return true;
if (getClass() != obj.getClass())
return false;
ChoiceFormat other = (ChoiceFormat) obj;
return (Utility.arrayEquals(choiceLimits,other.choiceLimits)
&& Utility.arrayEquals(choiceFormats,other.choiceFormats));
}
// ===============privates===========================
private double[] choiceLimits;
private String[] choiceFormats;
/*
static final long SIGN = 0x8000000000000000L;
static final long EXPONENT = 0x7FF0000000000000L;
static final long SIGNIFICAND = 0x000FFFFFFFFFFFFFL;
private static double nextDouble (double d, boolean positive) {
if (Double.isNaN(d) || Double.isInfinite(d)) {
return d;
}
long bits = Double.doubleToLongBits(d);
long significand = bits & SIGNIFICAND;
if (bits < 0) {
significand |= (SIGN | EXPONENT);
}
long exponent = bits & EXPONENT;
if (positive) {
significand += 1;
// FIXME fix overflow & underflow
} else {
significand -= 1;
// FIXME fix overflow & underflow
}
bits = exponent | (significand & ~EXPONENT);
return Double.longBitsToDouble(bits);
}
*/
/*
* Finds the least double greater than d (if positive == true),
* or the greatest double less than d (if positive == false).
* If NaN, returns same value.
*
* Does not affect floating-point flags,
* provided these member functions do not:
* Double.longBitsToDouble ()
* Double.doubleToLongBits ()
* Double.IsNaN ()
*/
static final long SIGN = 0x8000000000000000L;
static final long EXPONENT = 0x7FF0000000000000L;
static final long POSITIVEINFINITY = 0x7FF0000000000000L;
public static double nextDouble (double d, boolean positive) {
/* filter out NaN's */
if (Double.isNaN(d)) {
return d;
}
/* zero's are also a special case */
if (d == 0.0) {
double smallestPositiveDouble = Double.longBitsToDouble(1L);
if (positive) {
return smallestPositiveDouble;
} else {
return -smallestPositiveDouble;
}
}
/* if entering here, d is a nonzero value */
/* hold all bits in a long for later use */
long bits = Double.doubleToLongBits(d);
/* strip off the sign bit */
long magnitude = bits & ~SIGN;
/* if next double away from zero, increase magnitude */
if ((bits > 0) == positive) {
if (magnitude != POSITIVEINFINITY) {
magnitude += 1;
}
}
/* else decrease magnitude */
else {
magnitude -= 1;
}
/* restore sign bit and return */
long signbit = bits & SIGN;
return Double.longBitsToDouble (magnitude | signbit);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?