// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2009-2011 Google, All Rights reserved
// Copyright 2011-2012 MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
package com.google.appinventor.components.runtime.util;
import android.util.Log;
import java.text.*;
import java.util.Locale;
/**
* Convert inexact numbers to strings for printing in App Inventor.
* Kawa's default shows too many decimal places.
*
* @author halabelson@google.com (Hal Abelson)
*/
public final class YailNumberToString {
static final String LOG_TAG = "YailNumberToString";
// format magnitudes larger than BIGBOUND in scientific notation
private static final double BIGBOUND = 1.e6;
// format magnitudes smaller than SMALLBOUND in scientific notation
private static final double SMALLBOUND = 1.e-6;
// TODO(halabelson): The Java documentation warns that formatters are
// not thread-safe. Is there any way that this can bite us?
// format for decimal notation
private static final String decPattern = "#####0.0####";
// format for scientific notation
private static final String sciPattern = "0.####E0";
// TODO(hal): We are making the decimal separator be a period, regardless of
// the locale of the phone. We need to think about how to allow comma as decimal separator,
// which will require updating number parsing and other places that transform numbers to strings,
// such as FormatAsDecimal
static Locale locale = Locale.US;
static DecimalFormatSymbols symbols = new DecimalFormatSymbols(locale);
static DecimalFormat decimalFormat = new DecimalFormat(decPattern, symbols);
static DecimalFormat sciFormat = new DecimalFormat(sciPattern, symbols);
// TODO(halabelson): DecimalFormat scientific notation apparently does not provide a
// way to specify the maximum number of digits in the mantissa. One consequence is that this
// formatting method, when given floats of very large magnitude, will produce too many
// places in the mantissa. Consider post-processing the result of
// DecimalFormat to remove these extra digits.
// This implementation assumes that Kawa inexact numbers are passed to this routine
// as doubles.
public static String format(double number) {
// We will print integer values without a decimal point.
if (number == Math.rint(number)) {
return String.valueOf((int) number);
} else {
double mag = Math.abs(number);
if (mag < BIGBOUND && mag > SMALLBOUND) {
return decimalFormat.format(number);
} else {
return sciFormat.format(number);
}
}
}
}