Esempio n. 1
0
    /**
     * Format a number supplied as a decimal
     *
     * @param dval the decimal value
     * @param fsb the FastStringBuffer to contain the result
     */
    private void formatDecimal(BigDecimal dval, FastStringBuffer fsb) {
      dval = dval.setScale(maxFractionPartSize, BigDecimal.ROUND_HALF_EVEN);
      DecimalValue.decimalToString(dval, fsb);

      int point = fsb.indexOf('.');
      int intDigits;
      if (point >= 0) {
        int zz = maxFractionPartSize - minFractionPartSize;
        while (zz > 0) {
          if (fsb.charAt(fsb.length() - 1) == '0') {
            fsb.setLength(fsb.length() - 1);
            zz--;
          } else {
            break;
          }
        }
        intDigits = point;
        if (fsb.charAt(fsb.length() - 1) == '.') {
          fsb.setLength(fsb.length() - 1);
        }
      } else {
        intDigits = fsb.length();
        if (minFractionPartSize > 0) {
          fsb.append('.');
          for (int i = 0; i < minFractionPartSize; i++) {
            fsb.append('0');
          }
        }
      }
      if (minWholePartSize == 0 && intDigits == 1 && fsb.charAt(0) == '0') {
        fsb.removeCharAt(0);
      } else {
        fsb.prependRepeated('0', minWholePartSize - intDigits);
      }
    }
Esempio n. 2
0
    /**
     * Format a number using this sub-picture
     *
     * @param value the absolute value of the number to be formatted
     * @param dfs the decimal format symbols to be used
     * @param minusSign the representation of a minus sign to be used
     * @return the formatted number
     */
    public CharSequence format(NumericValue value, DecimalSymbols dfs, String minusSign) {

      // System.err.println("Formatting " + value);

      if (value.isNaN()) {
        return dfs.NaN; // changed by W3C Bugzilla 2712
      }

      if ((value instanceof DoubleValue || value instanceof FloatValue)
          && Double.isInfinite(value.getDoubleValue())) {
        return minusSign + prefix + dfs.infinity + suffix;
      }

      int multiplier = 1;
      if (isPercent) {
        multiplier = 100;
      } else if (isPerMille) {
        multiplier = 1000;
      }

      if (multiplier != 1) {
        try {
          // value = value.arithmetic(Token.MULT, new Int64Value(multiplier), null);
          value =
              (NumericValue)
                  ArithmeticExpression.compute(
                      value, Calculator.TIMES, new Int64Value(multiplier), null);
        } catch (XPathException e) {
          value = new DoubleValue(value.getDoubleValue() * multiplier);
        }
      }

      FastStringBuffer sb = new FastStringBuffer(20);
      if (value instanceof DoubleValue || value instanceof FloatValue) {
        BigDecimal dec = adjustToDecimal(value.getDoubleValue(), 2);
        formatDecimal(dec, sb);

        // formatDouble(value.getDoubleValue(), sb);

      } else if (value instanceof Int64Value || value instanceof BigIntegerValue) {
        formatInteger(value, sb);

      } else if (value instanceof DecimalValue) {
        //noinspection RedundantCast
        formatDecimal(((DecimalValue) value).getDecimalValue(), sb);
      }

      // System.err.println("Justified number: " + sb.toString());

      // Map the digits and decimal point to use the selected characters

      int[] ib = StringValue.expand(sb);
      int ibused = ib.length;
      int point = sb.indexOf('.');
      if (point == -1) {
        point = sb.length();
      } else {
        ib[point] = dfs.decimalSeparator;

        // If there is no fractional part, delete the decimal point
        if (maxFractionPartSize == 0) {
          ibused--;
        }
      }

      // Map the digits

      if (dfs.zeroDigit != '0') {
        int newZero = dfs.zeroDigit;
        for (int i = 0; i < ibused; i++) {
          int c = ib[i];
          if (c >= '0' && c <= '9') {
            ib[i] = (c - '0' + newZero);
          }
        }
      }

      // Add the whole-part grouping separators

      if (wholePartGroupingPositions != null) {
        if (wholePartGroupingPositions.length == 1) {
          // grouping separators are at regular positions
          int g = wholePartGroupingPositions[0];
          int p = point - g;
          while (p > 0) {
            ib = insert(ib, ibused++, dfs.groupingSeparator, p);
            // sb.insert(p, unicodeChar(dfs.groupingSeparator));
            p -= g;
          }
        } else {
          // grouping separators are at irregular positions
          for (int i = 0; i < wholePartGroupingPositions.length; i++) {
            int p = point - wholePartGroupingPositions[i];
            if (p > 0) {
              ib = insert(ib, ibused++, dfs.groupingSeparator, p);
              // sb.insert(p, unicodeChar(dfs.groupingSeparator));
            }
          }
        }
      }

      // Add the fractional-part grouping separators

      if (fractionalPartGroupingPositions != null) {
        // grouping separators are at irregular positions.
        for (int i = 0; i < fractionalPartGroupingPositions.length; i++) {
          int p = point + 1 + fractionalPartGroupingPositions[i] + i;
          if (p < ibused - 1) {
            ib = insert(ib, ibused++, dfs.groupingSeparator, p);
            // sb.insert(p, dfs.groupingSeparator);
          } else {
            break;
          }
        }
      }

      // System.err.println("Grouped number: " + sb.toString());

      // sb.insert(0, prefix);
      // sb.insert(0, minusSign);
      // sb.append(suffix);
      FastStringBuffer res =
          new FastStringBuffer(prefix.length() + minusSign.length() + suffix.length() + ibused);
      res.append(minusSign);
      res.append(prefix);
      res.append(StringValue.contract(ib, ibused));
      res.append(suffix);
      return res;
    }