diff --git a/app/src/main/java/org/solovyev/android/calculator/Engine.java b/app/src/main/java/org/solovyev/android/calculator/Engine.java index cdf8263b..e9939b9d 100644 --- a/app/src/main/java/org/solovyev/android/calculator/Engine.java +++ b/app/src/main/java/org/solovyev/android/calculator/Engine.java @@ -37,6 +37,7 @@ import org.solovyev.android.prefs.CharacterPreference; import org.solovyev.android.prefs.IntegerPreference; import org.solovyev.android.prefs.Preference; import org.solovyev.android.prefs.StringPreference; +import org.solovyev.common.NumberFormatter; import org.solovyev.common.text.EnumMapper; import org.solovyev.common.text.NumberMapper; @@ -93,7 +94,7 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene public Engine(@Nonnull JsclMathEngine mathEngine) { this.mathEngine = mathEngine; - this.mathEngine.setRoundResult(true); + this.mathEngine.setPrecision(5); this.mathEngine.setGroupingSeparator(JsclMathEngine.GROUPING_SEPARATOR_DEFAULT); } @@ -193,13 +194,24 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene final boolean scientific = preferences.getBoolean("engine.output.science_notation", false); Preferences.Output.notation.putPreference(editor, scientific ? Notation.sci : Notation.dec); } - migratePreference(preferences, Preferences.Output.round, "org.solovyev.android.calculator.CalculatorModel_round_result", editor); + if (preferences.contains("org.solovyev.android.calculator.CalculatorModel_round_result")) { + final boolean round = preferences.getBoolean("org.solovyev.android.calculator.CalculatorModel_round_result", true); + if (!round) { + Preferences.Output.precision.putPreference(editor, NumberFormatter.MAX_PRECISION); + } + } } else if (oldVersion == 1) { migratePreference(preferences, Preferences.Output.separator, "engine.groupingSeparator", editor); if (preferences.contains("engine.output.scientificNotation")) { final boolean scientific = preferences.getBoolean("engine.output.scientificNotation", false); Preferences.Output.notation.putPreference(editor, scientific ? Notation.sci : Notation.dec); } + if (preferences.contains("engine.output.round")) { + final boolean round = preferences.getBoolean("engine.output.round", true); + if (!round) { + Preferences.Output.precision.putPreference(editor, NumberFormatter.MAX_PRECISION); + } + } } Preferences.version.putDefault(editor); editor.apply(); @@ -228,7 +240,6 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene mathEngine.setPrecision(Preferences.Output.precision.getPreference(preferences)); mathEngine.setNotation(Preferences.Output.notation.getPreference(preferences).id); - mathEngine.setRoundResult(Preferences.Output.round.getPreference(preferences)); mathEngine.setGroupingSeparator(Preferences.Output.separator.getPreference(preferences)); bus.post(ChangedEvent.INSTANCE); @@ -284,7 +295,6 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene preferenceKeys.add(numeralBase.getKey()); preferenceKeys.add(angleUnit.getKey()); preferenceKeys.add(Output.precision.getKey()); - preferenceKeys.add(Output.round.getKey()); preferenceKeys.add(Output.notation.getKey()); preferenceKeys.add(Output.separator.getKey()); } @@ -296,7 +306,6 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene public static class Output { public static final StringPreference precision = StringPreference.ofTypedValue("engine.output.precision", "5", NumberMapper.of(Integer.class)); - public static final BooleanPreference round = BooleanPreference.of("engine.output.round", true); public static final StringPreference notation = StringPreference.ofEnum("engine.output.notation", Notation.dec, Notation.class); public static final CharacterPreference separator = CharacterPreference.of("engine.output.separator", JsclMathEngine.GROUPING_SEPARATOR_DEFAULT); } diff --git a/app/src/main/java/org/solovyev/android/calculator/preferences/NumberFormatPreference.java b/app/src/main/java/org/solovyev/android/calculator/preferences/NumberFormatPreference.java index 484dc9ca..8a36d481 100644 --- a/app/src/main/java/org/solovyev/android/calculator/preferences/NumberFormatPreference.java +++ b/app/src/main/java/org/solovyev/android/calculator/preferences/NumberFormatPreference.java @@ -17,10 +17,10 @@ import org.solovyev.android.calculator.Named; import org.solovyev.android.calculator.R; import org.solovyev.android.calculator.text.NaturalComparator; import org.solovyev.android.views.DiscreteSeekBar; +import org.solovyev.common.NumberFormatter; import butterknife.Bind; import butterknife.ButterKnife; -import jscl.JsclMathEngine; import static org.solovyev.android.calculator.Engine.Preferences.Output; @@ -112,7 +112,7 @@ public class NumberFormatPreference extends DialogPreference { private ArrayAdapter> makeSeparatorAdapter() { final Context context = getContext(); final ArrayAdapter> adapter = App.makeSimpleSpinnerAdapter(context); - adapter.add(Named.create(JsclMathEngine.GROUPING_SEPARATOR_NO, R.string.p_grouping_separator_no, context)); + adapter.add(Named.create(NumberFormatter.NO_GROUPING, R.string.p_grouping_separator_no, context)); adapter.add(Named.create('\'', R.string.p_grouping_separator_apostrophe, context)); adapter.add(Named.create(' ', R.string.p_grouping_separator_space, context)); return adapter; diff --git a/app/src/main/java/org/solovyev/android/calculator/preferences/PreferencesFragment.java b/app/src/main/java/org/solovyev/android/calculator/preferences/PreferencesFragment.java index b360c9e1..1f441473 100644 --- a/app/src/main/java/org/solovyev/android/calculator/preferences/PreferencesFragment.java +++ b/app/src/main/java/org/solovyev/android/calculator/preferences/PreferencesFragment.java @@ -13,7 +13,6 @@ import android.view.View; import android.widget.ListView; import org.solovyev.android.calculator.AdView; -import org.solovyev.android.calculator.Engine; import org.solovyev.android.calculator.Preferences; import org.solovyev.android.calculator.Preferences.Gui.Theme; import org.solovyev.android.calculator.R; @@ -135,8 +134,6 @@ public class PreferencesFragment extends org.solovyev.android.material.preferenc }); } }); - - onSharedPreferenceChanged(preferences, Engine.Preferences.Output.round.getKey()); } private void prepareLayoutPreference(int preference) { @@ -221,12 +218,6 @@ public class PreferencesFragment extends org.solovyev.android.material.preferenc @Override public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { - if (Engine.Preferences.Output.round.getKey().equals(key)) { - final Preference preference = findPreference(Engine.Preferences.Output.precision.getKey()); - if (preference != null) { - preference.setEnabled(preferences.getBoolean(key, Engine.Preferences.Output.round.getDefaultValue())); - } - } } @Override diff --git a/app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorMode.java b/app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorMode.java index 6720ac8d..d1be8929 100644 --- a/app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorMode.java +++ b/app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorMode.java @@ -26,6 +26,7 @@ import android.content.SharedPreferences; import org.solovyev.android.calculator.Engine; import org.solovyev.android.calculator.Preferences; +import org.solovyev.common.NumberFormatter; import javax.annotation.Nonnull; @@ -41,7 +42,7 @@ enum CalculatorMode { Preferences.Gui.mode.putPreference(editor, Preferences.Gui.Mode.simple); Engine.Preferences.angleUnit.putPreference(editor, AngleUnit.deg); Engine.Preferences.Output.notation.putPreference(editor, Engine.Notation.dec); - Engine.Preferences.Output.round.putPreference(editor, true); + Engine.Preferences.Output.precision.putPreference(editor, 5); editor.apply(); } @@ -55,7 +56,7 @@ enum CalculatorMode { Preferences.Gui.mode.putPreference(editor, Preferences.Gui.Mode.engineer); Engine.Preferences.angleUnit.putPreference(editor, AngleUnit.rad); Engine.Preferences.Output.notation.putPreference(editor, Engine.Notation.eng); - Engine.Preferences.Output.round.putPreference(editor, false); + Engine.Preferences.Output.precision.putPreference(editor, NumberFormatter.MAX_PRECISION); editor.apply(); } diff --git a/jscl/src/main/java/jscl/JsclMathEngine.java b/jscl/src/main/java/jscl/JsclMathEngine.java index 43fec261..022a7e92 100644 --- a/jscl/src/main/java/jscl/JsclMathEngine.java +++ b/jscl/src/main/java/jscl/JsclMathEngine.java @@ -36,8 +36,6 @@ public class JsclMathEngine implements MathEngine { public static final AngleUnit DEFAULT_ANGLE_UNITS = AngleUnit.deg; public static final NumeralBase DEFAULT_NUMERAL_BASE = NumeralBase.dec; public static final char GROUPING_SEPARATOR_DEFAULT = ' '; - public static final char GROUPING_SEPARATOR_NO = 0; - public static final int MAX_FRACTION_DIGITS = 20; @Nonnull private static JsclMathEngine instance = new JsclMathEngine(); @Nonnull @@ -49,10 +47,9 @@ public class JsclMathEngine implements MathEngine { return new NumberFormatter(); } }; - private char groupingSeparator = GROUPING_SEPARATOR_NO; - private boolean roundResult = false; + private char groupingSeparator = NumberFormatter.NO_GROUPING; private int notation = FSE_NONE; - private int precision = 5; + private int precision = NumberFormatter.MAX_PRECISION; @Nonnull private AngleUnit angleUnits = DEFAULT_ANGLE_UNITS; @Nonnull @@ -182,7 +179,7 @@ public class JsclMathEngine implements MathEngine { private NumberFormatter prepareNumberFormatter(@Nonnull NumeralBase nb) { final NumberFormatter nf = numberFormatter.get(); nf.setGroupingSeparator(hasGroupingSeparator() ? getGroupingSeparatorChar(nb) : NumberFormatter.NO_GROUPING); - nf.setPrecision(roundResult ? precision : NumberFormatter.NO_ROUNDING); + nf.setPrecision(precision); switch (notation) { case FSE_ENG: nf.useEngineeringFormat(NumberFormatter.DEFAULT_MAGNITUDE); @@ -264,7 +261,7 @@ public class JsclMathEngine implements MathEngine { ungroupedValue = to.toString(new BigDecimal(value).toBigInteger()); } catch (NotIntegerException e) { - ungroupedValue = to.toString(value, roundResult ? precision : MAX_FRACTION_DIGITS); + ungroupedValue = to.toString(value, precision); } return addGroupingSeparators(to, ungroupedValue); @@ -309,7 +306,7 @@ public class JsclMathEngine implements MathEngine { } private boolean hasGroupingSeparator() { - return groupingSeparator != JsclMathEngine.GROUPING_SEPARATOR_NO; + return groupingSeparator != NumberFormatter.NO_GROUPING; } @Nonnull @@ -347,10 +344,6 @@ public class JsclMathEngine implements MathEngine { return result; } - public void setRoundResult(boolean roundResult) { - this.roundResult = roundResult; - } - public void setPrecision(int precision) { this.precision = precision; } diff --git a/jscl/src/main/java/jscl/MathContext.java b/jscl/src/main/java/jscl/MathContext.java index f71c3d3e..2a9dcdb3 100644 --- a/jscl/src/main/java/jscl/MathContext.java +++ b/jscl/src/main/java/jscl/MathContext.java @@ -38,8 +38,6 @@ public interface MathContext { void setNumeralBase(@Nonnull NumeralBase numeralBase); - void setRoundResult(boolean roundResult); - void setPrecision(int precision); void setGroupingSeparator(char separator); diff --git a/jscl/src/main/java/org/solovyev/common/NumberFormatter.java b/jscl/src/main/java/org/solovyev/common/NumberFormatter.java index b875774d..8c824e98 100644 --- a/jscl/src/main/java/org/solovyev/common/NumberFormatter.java +++ b/jscl/src/main/java/org/solovyev/common/NumberFormatter.java @@ -1,17 +1,21 @@ package org.solovyev.common; -import midpcalc.Real; - -import javax.annotation.Nonnull; import java.math.BigDecimal; import java.math.BigInteger; +import javax.annotation.Nonnull; + +import midpcalc.Real; + import static java.lang.Math.pow; -import static midpcalc.Real.NumberFormat.*; +import static midpcalc.Real.NumberFormat.FSE_ENG; +import static midpcalc.Real.NumberFormat.FSE_FIX; +import static midpcalc.Real.NumberFormat.FSE_NONE; +import static midpcalc.Real.NumberFormat.FSE_SCI; public class NumberFormatter { - public static final int NO_GROUPING = 0; + public static final char NO_GROUPING = 0; public static final int NO_ROUNDING = -1; public static final int DEFAULT_MAGNITUDE = 5; public static final int MAX_PRECISION = 16; @@ -94,7 +98,6 @@ public class NumberFormatter { final BigInteger absValue = value.abs(); final boolean simpleFormat = useSimpleFormat(radix, absValue); - final int effectivePrecision = precision == NO_ROUNDING ? MAX_PRECISION : precision; if (simpleFormat) { numberFormat.fse = FSE_FIX; } else if (format == FSE_NONE) { @@ -105,7 +108,7 @@ public class NumberFormatter { numberFormat.fse = format; } numberFormat.thousand = groupingSeparator; - numberFormat.precision = effectivePrecision; + numberFormat.precision = Math.max(0, Math.min(precision, MAX_PRECISION)); numberFormat.base = radix; numberFormat.maxwidth = simpleFormat ? 100 : 30; diff --git a/jscl/src/test/java/jscl/JsclMathEngineTest.java b/jscl/src/test/java/jscl/JsclMathEngineTest.java index 49eec1f8..d2e3583f 100644 --- a/jscl/src/test/java/jscl/JsclMathEngineTest.java +++ b/jscl/src/test/java/jscl/JsclMathEngineTest.java @@ -2,6 +2,7 @@ package jscl; import org.junit.Before; import org.junit.Test; +import org.solovyev.common.NumberFormatter; import midpcalc.Real; @@ -39,7 +40,6 @@ public class JsclMathEngineTest { assertEquals("1 0100", me.format(20d, NumeralBase.bin)); assertEquals("1 1111", me.format(31d, NumeralBase.bin)); - me.setRoundResult(true); me.setPrecision(10); assertEquals("111 1111 0011 0110", me.format(32566d, NumeralBase.bin)); @@ -57,11 +57,11 @@ public class JsclMathEngineTest { assertEquals("D 25 0F 77 0A.6F7319", me.format(56456345354.43534534523459999d, NumeralBase.hex)); assertEquals("3 E7.4CCCCCCCCD", me.format(999.3d, NumeralBase.hex)); - me.setRoundResult(false); + me.setPrecision(NumberFormatter.MAX_PRECISION); assertEquals("6.CCDA6A054226DB6E-19", me.format(0.00000000000000000000009d, NumeralBase.hex)); assertEquals("A.E15D766ED03E2BEE-20", me.format(0.000000000000000000000009d, NumeralBase.hex)); } finally { - me.setGroupingSeparator(JsclMathEngine.GROUPING_SEPARATOR_NO); + me.setGroupingSeparator(NumberFormatter.NO_GROUPING); } assertEquals("1", me.format(1d, NumeralBase.bin)); @@ -108,7 +108,6 @@ public class JsclMathEngineTest { @Test public void testEngineeringNotationWithRounding() throws Exception { me.setNotation(Real.NumberFormat.FSE_ENG); - me.setRoundResult(true); me.setPrecision(5); assertEquals("10E6", me.format(10000000d)); @@ -164,7 +163,7 @@ public class JsclMathEngineTest { @Test public void testEngineeringNotationWithoutRounding() throws Exception { me.setNotation(Real.NumberFormat.FSE_ENG); - me.setRoundResult(false); + me.setPrecision(NumberFormatter.MAX_PRECISION); assertEquals("10E6", me.format(10000000d)); assertEquals("99E6", me.format(99000000d)); diff --git a/jscl/src/test/java/jscl/math/ExpressionTest.java b/jscl/src/test/java/jscl/math/ExpressionTest.java index 7e76fb0b..a45fbc7b 100644 --- a/jscl/src/test/java/jscl/math/ExpressionTest.java +++ b/jscl/src/test/java/jscl/math/ExpressionTest.java @@ -1,6 +1,7 @@ package jscl.math; import org.junit.Test; +import org.solovyev.common.NumberFormatter; import java.io.BufferedReader; import java.io.IOException; @@ -804,20 +805,17 @@ public class ExpressionTest { assertEquals("100", Expression.valueOf("100.0").simplify().toString()); me.setNotation(Real.NumberFormat.FSE_NONE); - me.setRoundResult(true); me.setPrecision(5); assertEquals("0", Expression.valueOf("1222/(10^9)").numeric().toString()); me.setNotation(Real.NumberFormat.FSE_SCI); - me.setRoundResult(true); me.setPrecision(5); assertEquals("1.222E-6", Expression.valueOf("1222/(10^9)").numeric().toString()); - me.setRoundResult(true); me.setPrecision(10); assertEquals("1.222E-6", Expression.valueOf("1222/(10^9)").numeric().toString()); - me.setRoundResult(false); + me.setPrecision(NumberFormatter.MAX_PRECISION); assertEquals("1.222E-6", Expression.valueOf("1222/(10^9)").numeric().toString()); me.setNotation(Real.NumberFormat.FSE_NONE); @@ -826,19 +824,17 @@ public class ExpressionTest { me.setNotation(Real.NumberFormat.FSE_SCI); assertEquals("0.3333333333333333", Expression.valueOf("1/3").numeric().toString()); - me.setRoundResult(true); me.setPrecision(10); assertEquals("0.3333333333", Expression.valueOf("1/3").numeric().toString()); me.setNotation(Real.NumberFormat.FSE_NONE); - me.setRoundResult(true); me.setPrecision(10); assertEquals("0.3333333333", Expression.valueOf("1/3").numeric().toString()); } finally { - me.setGroupingSeparator(JsclMathEngine.GROUPING_SEPARATOR_NO); + me.setGroupingSeparator(NumberFormatter.NO_GROUPING); me.setNotation(Real.NumberFormat.FSE_NONE); - me.setRoundResult(false); + me.setPrecision(NumberFormatter.MAX_PRECISION); } } }