/*
* $Id: AnyNumber.java,v 1.5 2002/09/16 08:05:02 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.core;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import anvil.script.Context;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
/// @class number
/// Abstract base class for integers and floats.
/**
* class <code>AnyNumber</code>.
*
* @author Jani Lehtim�ki
* @version $Revision: 1.5 $
*/
public abstract class AnyNumber extends Any
{
protected long _long;
protected AnyNumber()
{
}
public anvil.script.ClassType classOf()
{
return __class__;
}
/// @method format
/// Formats number according to given rules in format string.
/// Documentation taken from <code>java.text.DecimalFormat</code>.
///
/// <p><strong>Structure of the pattern:</strong>
/// <pre>
/// pattern := subpattern{;subpattern}
/// subpattern := {prefix}integer{.fraction}{suffix}
///
/// prefix := '\\u0000'..'\\uFFFD' - specialCharacters
/// suffix := '\\u0000'..'\\uFFFD' - specialCharacters
/// integer := '#'* '0'* '0'
/// fraction := '0'* '#'*
///
/// Notation:
/// X* 0 or more instances of X
/// (X | Y) either X or Y.
/// X..Y any character from X up to Y, inclusive.
/// S - T characters in S, except those in T
/// </pre>
/// The first subpattern is for positive numbers. The second (optional)
/// subpattern is for negative numbers. (In both cases, ',' can occur
/// inside the integer portion--it is just too messy to indicate in BNF.)
///
/// <p>
/// Here are the special characters used in the parts of the
/// subpattern, with notes on their usage.
/// <pre>
/// Symbol Meaning
/// 0 a digit
/// # a digit, zero shows as absent
/// . placeholder for decimal separator
/// , placeholder for grouping separator.
/// E separates mantissa and exponent for exponential formats.
/// ; separates formats.
/// - default negative prefix.
/// % multiply by 100 and show as percentage
/// ? multiply by 1000 and show as per mille
/// \244 currency sign; replaced by currency symbol; if
/// doubled, replaced by international currency symbol.
/// If present in a pattern, the monetary decimal separator
/// is used instead of the decimal separator.
/// X any other characters can be used in the prefix or suffix
/// ' used to quote special characters in a prefix or suffix.
/// </pre>
/// <p><strong>Notes</strong>
/// <p>
/// If there is no explicit negative subpattern, - is prefixed to the
/// positive form. That is, "0.00" alone is equivalent to "0.00;-0.00".
/// If there is an explicit negative subpattern, it serves only to specify the
/// negative prefix and suffix; the number of digits, minimal digits, and other
/// characteristics are all the same as the positive pattern. That means that
/// "#,##0.0#;(#)" has precisely the same result as "#,##0.0#;(#,##0.0#)".
///
/// <p>If the maximum number of fraction digits is lower than the actual number
/// of fraction digits, then <code>format()</code> will round the result to the
/// maximum number of fraction digits. The rounding is performed according to
/// the IEEE 754 default rounding mode known as <em>half even</em>: Numbers are
/// rounded toward the nearest truncated value, unless both truncated values are
/// equidistant, in which case the value ending in an even digit is chosen.
///
/// <p>For example, formatting the number 1.2499 with a maximum of two fraction
/// digits gives two possible values, 1.24 and 1.25. The distance to 1.24 is
/// 0.0099 and the distance to 1.25 is 0.0001, so 1.25 is chosen. On the other
/// hand, when rounding 1.245 to two fraction digits, the two possible values are
/// again 1.24 and 1.25, but the distance to each is the same: 0.005. In this
/// case 1.24 is chosen because it ends in an even digit.
///
/// <p>
/// The exponent character must be immediately followed by one or more
/// digit characters. Example: "0.###E0". The number of digit characters
/// after the exponent character gives the minimum exponent digit count;
/// there is no maximum. Negative exponents are denoted using the same
/// prefix and/or suffix specified for the number itself. The minimum
/// number of integer digits is achieved by adjusting the exponent. The
/// maximum number of integer digits, if any, specifies the exponent
/// grouping. For example, 12345 is formatted using "##0.###E0" as
/// "12.345E3".
/// <p>
/// Illegal patterns, such as "#.#.#" or mixing '_' and '*' in the
/// same pattern, will cause an <code>IllegalArgumentException</code> to be
/// thrown. From the message of <code>IllegalArgumentException</code>, you can
/// find the place in the string where the error occurred.
///
/// <p>
/// The grouping separator is commonly used for thousands, but in some
/// countries for ten-thousands. The interval is a constant number of
/// digits between the grouping characters, such as 100,000,000 or 1,0000,0000.
/// If you supply a pattern with multiple grouping characters, the interval
/// between the last one and the end of the integer is the one that is
/// used. So "#,##,###,####" == "######,####" == "##,####,####".
///
/// <p>
/// When parsing fails, null is returned.
///
/// @synopsis string format(string format)
/// @return Number formatted, or <code>null</code> if parsing failed.
/// @throws BadParameter If format string was invalid
public static final Object[] p_format = new Object[] { "format" };
public Any m_format(Context context, String format)
{
try {
DecimalFormatSymbols dfsymbols = new DecimalFormatSymbols(context.getLocale());
DecimalFormat df = new DecimalFormat(format, dfsymbols);
if (typeOf() == IS_INT) {
return Any.create(df.format(toLong()));
} else {
return Any.create(df.format(toDouble()));
}
} catch (IllegalArgumentException e) {
throw context.BadParameter(e.getMessage());
}
}
transient public static final anvil.script.compiler.NativeClass __class__ =
new anvil.script.compiler.NativeClass("number", AnyNumber.class,
//DOC{{
""+
" @class number\n" +
" Abstract base class for integers and floats.\n" +
" @method format\n" +
" Formats number according to given rules in format string.\n" +
" Documentation taken from <code>java.text.DecimalFormat</code>.\n" +
"\n" +
" <p><strong>Structure of the pattern:</strong>\n" +
" <pre>\n" +
" pattern := subpattern{;subpattern}\n" +
" subpattern := {prefix}integer{.fraction}{suffix}\n" +
"\n" +
" prefix := '\\u0000'..'\\uFFFD' - specialCharacters\n" +
" suffix := '\\u0000'..'\\uFFFD' - specialCharacters\n" +
" integer := '#'* '0'* '0'\n" +
" fraction := '0'* '#'*\n" +
"\n" +
" Notation:\n" +
" X* 0 or more instances of X\n" +
" (X | Y) either X or Y.\n" +
" X..Y any character from X up to Y, inclusive.\n" +
" S - T characters in S, except those in T\n" +
" </pre>\n" +
" The first subpattern is for positive numbers. The second (optional)\n" +
" subpattern is for negative numbers. (In both cases, ',' can occur\n" +
" inside the integer portion--it is just too messy to indicate in BNF.)\n" +
"\n" +
" <p>\n" +
" Here are the special characters used in the parts of the\n" +
" subpattern, with notes on their usage.\n" +
" <pre>\n" +
" Symbol Meaning\n" +
" 0 a digit\n" +
" # a digit, zero shows as absent\n" +
" . placeholder for decimal separator\n" +
" , placeholder for grouping separator.\n" +
" E separates mantissa and exponent for exponential formats.\n" +
" ; separates formats.\n" +
" - default negative prefix.\n" +
" % multiply by 100 and show as percentage\n" +
" ? multiply by 1000 and show as per mille\n" +
" \244 currency sign; replaced by currency symbol; if\n" +
" doubled, replaced by international currency symbol.\n" +
" If present in a pattern, the monetary decimal separator\n" +
" is used instead of the decimal separator.\n" +
" X any other characters can be used in the prefix or suffix\n" +
" ' used to quote special characters in a prefix or suffix.\n" +
" </pre>\n" +
" <p><strong>Notes</strong>\n" +
" <p>\n" +
" If there is no explicit negative subpattern, - is prefixed to the\n" +
" positive form. That is, \"0.00\" alone is equivalent to \"0.00;-0.00\".\n" +
" If there is an explicit negative subpattern, it serves only to specify the\n" +
" negative prefix and suffix; the number of digits, minimal digits, and other\n" +
" characteristics are all the same as the positive pattern. That means that\n" +
" \"#,##0.0#;(#)\" has precisely the same result as \"#,##0.0#;(#,##0.0#)\".\n" +
"\n" +
" <p>If the maximum number of fraction digits is lower than the actual number\n" +
" of fraction digits, then <code>format()</code> will round the result to the\n" +
" maximum number of fraction digits. The rounding is performed according to\n" +
" the IEEE 754 default rounding mode known as <em>half even</em>: Numbers are\n" +
" rounded toward the nearest truncated value, unless both truncated values are\n" +
" equidistant, in which case the value ending in an even digit is chosen.\n" +
" \n" +
" <p>For example, formatting the number 1.2499 with a maximum of two fraction\n" +
" digits gives two possible values, 1.24 and 1.25. The distance to 1.24 is\n" +
" 0.0099 and the distance to 1.25 is 0.0001, so 1.25 is chosen. On the other\n" +
" hand, when rounding 1.245 to two fraction digits, the two possible values are\n" +
" again 1.24 and 1.25, but the distance to each is the same: 0.005. In this\n" +
" case 1.24 is chosen because it ends in an even digit.\n" +
"\n" +
" <p>\n" +
" The exponent character must be immediately followed by one or more\n" +
" digit characters. Example: \"0.###E0\". The number of digit characters\n" +
" after the exponent character gives the minimum exponent digit count;\n" +
" there is no maximum. Negative exponents are denoted using the same\n" +
" prefix and/or suffix specified for the number itself. The minimum\n" +
" number of integer digits is achieved by adjusting the exponent. The\n" +
" maximum number of integer digits, if any, specifies the exponent\n" +
" grouping. For example, 12345 is formatted using \"##0.###E0\" as\n" +
" \"12.345E3\".\n" +
" <p>\n" +
" Illegal patterns, such as \"#.#.#\" or mixing '_' and '*' in the\n" +
" same pattern, will cause an <code>IllegalArgumentException</code> to be\n" +
" thrown. From the message of <code>IllegalArgumentException</code>, you can\n" +
" find the place in the string where the error occurred.\n" +
"\n" +
" <p>\n" +
" The grouping separator is commonly used for thousands, but in some\n" +
" countries for ten-thousands. The interval is a constant number of\n" +
" digits between the grouping characters, such as 100,000,000 or 1,0000,0000.\n" +
" If you supply a pattern with multiple grouping characters, the interval\n" +
" between the last one and the end of the integer is the one that is\n" +
" used. So \"#,##,###,####\" == \"######,####\" == \"##,####,####\".\n" +
"\n" +
" <p>\n" +
" When parsing fails, null is returned.\n" +
"\n" +
" @synopsis string format(string format)\n" +
" @return Number formatted, or <code>null</code> if parsing failed.\n" +
" @throws BadParameter If format string was invalid\n"
//}}DOC
);
}