diff options
author | Hans Boehm <hboehm@google.com> | 2015-06-20 01:20:43 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-06-20 01:20:43 +0000 |
commit | aafeaa046712478381b4d762437c2b756c3fac1c (patch) | |
tree | 8b594189caf3aefe628ea6b7018b6d367878b2c6 | |
parent | 7f83e36b7a1cb358b8dd44da842a3897b65bfdde (diff) | |
parent | f6dae114d7e7c5a2d2d5a6b0f2c8d1fc6cf2937f (diff) | |
download | android_packages_apps_ExactCalculator-aafeaa046712478381b4d762437c2b756c3fac1c.tar.gz android_packages_apps_ExactCalculator-aafeaa046712478381b4d762437c2b756c3fac1c.tar.bz2 android_packages_apps_ExactCalculator-aafeaa046712478381b4d762437c2b756c3fac1c.zip |
Merge "Fix "with leading digits" display." into mnc-dev
-rw-r--r-- | src/com/android/calculator2/CalculatorResult.java | 109 |
1 files changed, 62 insertions, 47 deletions
diff --git a/src/com/android/calculator2/CalculatorResult.java b/src/com/android/calculator2/CalculatorResult.java index 0c4c18f..d3cfa16 100644 --- a/src/com/android/calculator2/CalculatorResult.java +++ b/src/com/android/calculator2/CalculatorResult.java @@ -71,6 +71,8 @@ public class CalculatorResult extends AlignedTextView { private int mMaxCharPos; // The same, but in characters. private int mLsd; // Position of least-significant digit in result // (1 = tenths, -1 = tens), or Integer.MAX_VALUE. + private int mLastDisplayedDigit; // Position of last digit actually displayed after adding + // exponent. private final Object mWidthLock = new Object(); // Protects the next two fields. private int mWidthConstraint = -1; @@ -327,6 +329,10 @@ public class CalculatorResult extends AlignedTextView { // getString and thus identifies the significance of the rightmost digit. // A value of 1 means the rightmost digits corresponds to tenths. // maxDigs is the maximum number of characters in the result. + // We set lastDisplayedDigit[0] to the position of the last digit actually appearing in + // the display. + // If forcePrecision is true, we make sure that the last displayed digit corresponds to + // prec, and allow maxDigs to be exceeded in assing the exponent. // We add two distinct kinds of exponents: // 1) If the final result contains the leading digit we use standard scientific notation. // 2) If not, we add an exponent corresponding to an interpretation of the final result as @@ -336,9 +342,8 @@ public class CalculatorResult extends AlignedTextView { // would have been in had we not done so. // This minimizes jumps as a result of scrolling. Result is NOT internationalized, // uses "e" for exponent. - public String formatResult(String res, int prec, - int maxDigs, boolean truncated, - boolean negative) { + public String formatResult(String res, int prec, int maxDigs, boolean truncated, + boolean negative, int lastDisplayedDigit[], boolean forcePrecision) { int msd; // Position of most significant digit in res or indication its outside res. int minusSpace = negative ? 1 : 0; if (truncated) { @@ -349,6 +354,7 @@ public class CalculatorResult extends AlignedTextView { } int decIndex = res.indexOf('.'); int resLen = res.length(); + lastDisplayedDigit[0] = prec; if ((decIndex == -1 || msd != Evaluator.INVALID_MSD && msd - decIndex > MAX_LEADING_ZEROES + 1) && prec != -1) { // No decimal point displayed, and it's not just to the right of the last digit, @@ -368,7 +374,7 @@ public class CalculatorResult extends AlignedTextView { // with one digit to the left of the decimal point. Insert decimal point and // delete leading zeroes. // We try to keep leading digits roughly in position, and never - // lengthen the result by more than SCI_NOT_EXTRA. + // lengthen the result by more than SCI_NOTATION_EXTRA. String fraction = res.substring(msd + 1, resLen); res = (negative ? "-" : "") + res.substring(msd, msd + 1) + "." + fraction; exp += resLen - msd - 1; @@ -381,53 +387,65 @@ public class CalculatorResult extends AlignedTextView { // Actually add the exponent of either type: String expAsString = Integer.toString(exp); int expDigits = expAsString.length(); - int dropDigits = expDigits + 1; - // Drop digits even if there is room. Otherwise the scrolling gets jumpy. - if (dropDigits >= resLen - 1) { - dropDigits = Math.max(resLen - 2, 0); - // Jumpy is better than no mantissa. Probably impossible anyway. - } - if (!hasPoint) { - // Special handling for TYPE(2) EXPONENT: - exp += dropDigits; - expAsString = Integer.toString(exp); - // Adjust for digits we are about to drop to drop to make room for exponent. - // This can affect the room we have for the mantissa. We adjust only for - // positive exponents, when it could otherwise result in a truncated - // displayed result. - if (exp > 0 && expAsString.length() > expDigits) { - // ++expDigits; (dead code) - ++dropDigits; - ++exp; - expAsString = Integer.toString(exp); - // This cannot increase the length a second time. + if (!forcePrecision) { + int dropDigits = expDigits + 1; + // Drop digits even if there is room. Otherwise the scrolling gets jumpy. + if (dropDigits >= resLen - 1) { + dropDigits = Math.max(resLen - 2, 0); + // Jumpy is better than no mantissa. Probably impossible anyway. } - if (prec - dropDigits > mLsd) { - // This can happen if e.g. result = 10^40 + 10^10 - // It turns out we would otherwise display ...10e9 because - // it takes the same amount of space as ...1e10 but shows one more digit. - // But we don't want to display a trailing zero, even if it's free. - ++dropDigits; - ++exp; + if (!hasPoint) { + // Special handling for TYPE(2) EXPONENT: + exp += dropDigits; expAsString = Integer.toString(exp); + // Adjust for digits we are about to drop to drop to make room for exponent. + // This can affect the room we have for the mantissa. We adjust only for + // positive exponents, when it could otherwise result in a truncated + // displayed result. + if (exp > 0 && expAsString.length() > expDigits) { + // ++expDigits; (dead code) + ++dropDigits; + ++exp; + expAsString = Integer.toString(exp); + // This cannot increase the length a second time. + } + if (prec - dropDigits > mLsd) { + // This can happen if e.g. result = 10^40 + 10^10 + // It turns out we would otherwise display ...10e9 because it takes + // the same amount of space as ...1e10 but shows one more digit. + // But we don't want to display a trailing zero, even if it's free. + ++dropDigits; + ++exp; + expAsString = Integer.toString(exp); + } } + res = res.substring(0, resLen - dropDigits); + lastDisplayedDigit[0] -= dropDigits; } - res = res.substring(0, resLen - dropDigits); res = res + "e" + expAsString; } // else don't add zero exponent } return res; } - // Get formatted, but not internationalized, result from - // mEvaluator. - private String getFormattedResult(int pos, int maxSize) { + /** + * Get formatted, but not internationalized, result from mEvaluator. + * @param pos requested position (1 = tenths) of last included digit. + * @param maxSize Maximum number of characters (more or less) in result. + * @param lastDisplayedPrec Zeroth entry is set to actual position of last included digit, + * after adjusting for exponent, etc. + * @param forcePrecision Ensure that last included digit is at pos, at the expense + * of treating maxSize as a soft limit. + */ + private String getFormattedResult(int pos, int maxSize, int lastDisplayedDigit[], + boolean forcePrecision) { final boolean truncated[] = new boolean[1]; final boolean negative[] = new boolean[1]; final int requested_prec[] = {pos}; final String raw_res = mEvaluator.getString(requested_prec, mMaxCharPos, maxSize, truncated, negative); - return formatResult(raw_res, requested_prec[0], maxSize, truncated[0], negative[0]); + return formatResult(raw_res, requested_prec[0], maxSize, truncated[0], negative[0], + lastDisplayedDigit, forcePrecision); } // Return entire result (within reason) up to current displayed precision. @@ -435,19 +453,14 @@ public class CalculatorResult extends AlignedTextView { if (!mValid) return ""; if (!mScrollable) return getText().toString(); int currentCharPos = getCurrentCharPos(); - return KeyMaps.translateResult(getFormattedResult(currentCharPos, MAX_COPY_SIZE)); + int unused[] = new int[1]; + return KeyMaps.translateResult(getFormattedResult(mLastDisplayedDigit, MAX_COPY_SIZE, + unused, true)); } public boolean fullTextIsExact() { - BoundedRational rat = mEvaluator.getRational(); - int currentCharPos = getCurrentCharPos(); - if (currentCharPos == -1) { - // Suppressing decimal point; still showing all integral digits. - currentCharPos = 0; - } - // TODO: Could handle scientific notation cases better; - // We currently treat those conservatively as approximate. - return (currentCharPos >= BoundedRational.digitsRequired(rat)); + return !mScrollable + || mMaxCharPos == getCurrentCharPos() && mMaxCharPos != MAX_RIGHT_SCROLL; } /** @@ -493,7 +506,8 @@ public class CalculatorResult extends AlignedTextView { void redisplay() { int currentCharPos = getCurrentCharPos(); int maxChars = getMaxChars(); - String result = getFormattedResult(currentCharPos, maxChars); + int lastDisplayedDigit[] = new int[1]; + String result = getFormattedResult(currentCharPos, maxChars, lastDisplayedDigit, false); int epos = result.indexOf('e'); result = KeyMaps.translateResult(result); if (epos > 0 && result.indexOf('.') == -1) { @@ -505,6 +519,7 @@ public class CalculatorResult extends AlignedTextView { } else { setText(result); } + mLastDisplayedDigit = lastDisplayedDigit[0]; mValid = true; } |