Real should indicate error in parsing
This commit is contained in:
parent
b00e02a693
commit
af5bf16182
@ -1,7 +1,6 @@
|
|||||||
package org.solovyev.android.calculator.converter;
|
package org.solovyev.android.calculator.converter;
|
||||||
|
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import jscl.JsclMathEngine;
|
import jscl.JsclMathEngine;
|
||||||
@ -101,17 +100,21 @@ final class Converter {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double parse(@NonNull String value) {
|
@NonNull
|
||||||
|
public static Real parse(@NonNull String value) throws NumberFormatException {
|
||||||
return parse(value, 10);
|
return parse(value, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double parse(@NonNull String value, int base) {
|
@NonNull
|
||||||
|
public static Real parse(@NonNull String value, int base) throws NumberFormatException {
|
||||||
final String groupingSeparator = String.valueOf(JsclMathEngine.getInstance().getGroupingSeparator());
|
final String groupingSeparator = String.valueOf(JsclMathEngine.getInstance().getGroupingSeparator());
|
||||||
if (!TextUtils.isEmpty(groupingSeparator)) {
|
if (groupingSeparator.length() > 0) {
|
||||||
value = value.replace(groupingSeparator, "");
|
value = value.replace(groupingSeparator, "");
|
||||||
}
|
}
|
||||||
final Real real = new Real(value, base);
|
final Real real = new Real(value, base);
|
||||||
final long bits = real.toDoubleBits();
|
if (real.isNan()) {
|
||||||
return Double.longBitsToDouble(bits);
|
throw new NumberFormatException();
|
||||||
|
}
|
||||||
|
return real;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,39 +21,21 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.AdapterView;
|
import android.widget.*;
|
||||||
import android.widget.ArrayAdapter;
|
import butterknife.Bind;
|
||||||
import android.widget.EditText;
|
import butterknife.ButterKnife;
|
||||||
import android.widget.ImageButton;
|
import org.solovyev.android.calculator.*;
|
||||||
import android.widget.Spinner;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import org.solovyev.android.calculator.App;
|
|
||||||
import org.solovyev.android.calculator.AppComponent;
|
|
||||||
import org.solovyev.android.calculator.AppModule;
|
|
||||||
import org.solovyev.android.calculator.BaseDialogFragment;
|
|
||||||
import org.solovyev.android.calculator.Clipboard;
|
|
||||||
import org.solovyev.android.calculator.Editor;
|
|
||||||
import org.solovyev.android.calculator.Keyboard;
|
|
||||||
import org.solovyev.android.calculator.R;
|
|
||||||
import org.solovyev.android.calculator.keyboard.FloatingKeyboard;
|
import org.solovyev.android.calculator.keyboard.FloatingKeyboard;
|
||||||
import org.solovyev.android.calculator.keyboard.FloatingKeyboardWindow;
|
import org.solovyev.android.calculator.keyboard.FloatingKeyboardWindow;
|
||||||
import org.solovyev.android.calculator.keyboard.FloatingNumberKeyboard;
|
import org.solovyev.android.calculator.keyboard.FloatingNumberKeyboard;
|
||||||
import org.solovyev.android.calculator.math.MathUtils;
|
import org.solovyev.android.calculator.math.MathUtils;
|
||||||
import org.solovyev.android.calculator.view.EditTextCompat;
|
import org.solovyev.android.calculator.view.EditTextCompat;
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
import butterknife.Bind;
|
import static org.solovyev.android.calculator.UiPreferences.Converter.*;
|
||||||
import butterknife.ButterKnife;
|
|
||||||
|
|
||||||
import static org.solovyev.android.calculator.UiPreferences.Converter.lastDimension;
|
|
||||||
import static org.solovyev.android.calculator.UiPreferences.Converter.lastUnitsFrom;
|
|
||||||
import static org.solovyev.android.calculator.UiPreferences.Converter.lastUnitsTo;
|
|
||||||
|
|
||||||
public class ConverterFragment extends BaseDialogFragment
|
public class ConverterFragment extends BaseDialogFragment
|
||||||
implements AdapterView.OnItemSelectedListener, View.OnFocusChangeListener, TextView.OnEditorActionListener, View.OnClickListener, TextWatcher {
|
implements AdapterView.OnItemSelectedListener, View.OnFocusChangeListener, TextView.OnEditorActionListener, View.OnClickListener, TextWatcher {
|
||||||
@ -332,7 +314,7 @@ public class ConverterFragment extends BaseDialogFragment
|
|||||||
final String value = editTextFrom.getText().toString();
|
final String value = editTextFrom.getText().toString();
|
||||||
if (TextUtils.isEmpty(value)) {
|
if (TextUtils.isEmpty(value)) {
|
||||||
if (validate) {
|
if (validate) {
|
||||||
setError(labelFrom, "Empty");
|
setError(labelFrom, R.string.cpp_nan);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -345,7 +327,7 @@ public class ConverterFragment extends BaseDialogFragment
|
|||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
editTextTo.setText("");
|
editTextTo.setText("");
|
||||||
if (validate) {
|
if (validate) {
|
||||||
setError(labelFrom, e.getLocalizedMessage());
|
setError(labelFrom, R.string.cpp_nan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import android.support.annotation.NonNull;
|
|||||||
|
|
||||||
interface Convertible {
|
interface Convertible {
|
||||||
@NonNull
|
@NonNull
|
||||||
String convert(@NonNull Convertible to, @NonNull String value);
|
String convert(@NonNull Convertible to, @NonNull String value) throws NumberFormatException;
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
Named<Convertible> named(@NonNull Context context);
|
Named<Convertible> named(@NonNull Context context);
|
||||||
|
@ -4,6 +4,7 @@ import android.content.Context;
|
|||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import jscl.JsclMathEngine;
|
import jscl.JsclMathEngine;
|
||||||
import jscl.NumeralBase;
|
import jscl.NumeralBase;
|
||||||
|
import midpcalc.Real;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
|
||||||
@ -20,16 +21,17 @@ public class NumeralBaseConvertible implements Convertible {
|
|||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public String convert(@NonNull Convertible to, @NonNull String value) {
|
public String convert(@NonNull Convertible to, @NonNull String value) throws NumberFormatException {
|
||||||
final NumeralBase baseTo = ((NumeralBaseConvertible) to).base;
|
final NumeralBase baseTo = ((NumeralBaseConvertible) to).base;
|
||||||
try {
|
final Real real = Converter.parse(value, base.radix);
|
||||||
final BigInteger integer = base.toBigInteger(value);
|
if (real.isIntegral()) {
|
||||||
return mathEngine.format(integer, baseTo);
|
final long l = real.toLong();
|
||||||
} catch (NumberFormatException e) {
|
if (l != Long.MAX_VALUE && l != -Long.MAX_VALUE) {
|
||||||
final double d = Converter.parse(value, base.radix);
|
return mathEngine.format(BigInteger.valueOf(l), baseTo);
|
||||||
return mathEngine.format(d, baseTo);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return mathEngine.format(real.toDouble(), baseTo);
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
|
@ -34,7 +34,7 @@ final class UnitConvertible implements Convertible {
|
|||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public String convert(@NonNull Convertible to, @NonNull String value) {
|
public String convert(@NonNull Convertible to, @NonNull String value) {
|
||||||
final double from = Converter.parse(value);
|
final double from = Converter.parse(value).toDouble();
|
||||||
final double converted = unit.getConverterTo(((UnitConvertible) to).unit).convert(from);
|
final double converted = unit.getConverterTo(((UnitConvertible) to).unit).convert(from);
|
||||||
return format(converted);
|
return format(converted);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
package org.solovyev.android.calculator.converter;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class ConverterTest {
|
||||||
|
|
||||||
|
@Test(expected = NumberFormatException.class)
|
||||||
|
public void testShouldNotParseInvalidDecNumber() throws Exception {
|
||||||
|
Converter.parse("1A", 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testShouldParseValidHexNumber() throws Exception {
|
||||||
|
assertEquals(26, Converter.parse("1A", 16).toLong());
|
||||||
|
}
|
||||||
|
}
|
@ -771,8 +771,8 @@ public final class Real {
|
|||||||
* base-16: <code>"/FFF800C.CCCE e64"</code>
|
* base-16: <code>"/FFF800C.CCCE e64"</code>
|
||||||
* <p/>
|
* <p/>
|
||||||
* <p>The number is parsed until the end of the string or an unknown
|
* <p>The number is parsed until the end of the string or an unknown
|
||||||
* character is encountered, then silently returns even if the whole
|
* character is encountered. Note that in case of latter this Real becomes
|
||||||
* string has not been parsed. Please note that specifying an
|
* NAN. Please note that specifying an
|
||||||
* excessive number of digits in base-10 may in fact decrease the
|
* excessive number of digits in base-10 may in fact decrease the
|
||||||
* accuracy of the result because of the extra multiplications performed.
|
* accuracy of the result because of the extra multiplications performed.
|
||||||
* <p/>
|
* <p/>
|
||||||
@ -2243,6 +2243,10 @@ public final class Real {
|
|||||||
return (this.sign == 0) ? (mantissa >>> shift) : -(mantissa >>> shift);
|
return (this.sign == 0) ? (mantissa >>> shift) : -(mantissa >>> shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double toDouble() {
|
||||||
|
return Double.longBitsToDouble(toDoubleBits());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns <code>true</code> if the value of this <code>Real</code>
|
* Returns <code>true</code> if the value of this <code>Real</code>
|
||||||
* represents a mathematical integer. If the value is too large to
|
* represents a mathematical integer. If the value is too large to
|
||||||
@ -6184,6 +6188,10 @@ public final class Real {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sign = tmpSign;
|
sign = tmpSign;
|
||||||
|
if (index != length) {
|
||||||
|
// signal error
|
||||||
|
assign(NAN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
Loading…
Reference in New Issue
Block a user