diff --git a/core/java/android/hardware/camera2/Rational.java b/core/java/android/hardware/camera2/Rational.java index 0260e021dc98b..77b8c2685441d 100644 --- a/core/java/android/hardware/camera2/Rational.java +++ b/core/java/android/hardware/camera2/Rational.java @@ -26,22 +26,17 @@ public final class Rational { /** *
Create a Rational with a given numerator and denominator.
* - *- * The signs of the numerator and the denominator may be flipped such that the denominator - * is always 0. - *
+ *The signs of the numerator and the denominator may be flipped such that the denominator + * is always positive.
+ * + *A rational value with a 0-denominator may be constructed, but will have similar semantics + * as float NaN and INF values. The int getter functions return 0 in this case.
* * @param numerator the numerator of the rational * @param denominator the denominator of the rational - * - * @throws IllegalArgumentException if the denominator is 0 */ public Rational(int numerator, int denominator) { - if (denominator == 0) { - throw new IllegalArgumentException("Argument 'denominator' is 0"); - } - if (denominator < 0) { numerator = -numerator; denominator = -denominator; @@ -55,6 +50,9 @@ public final class Rational { * Gets the numerator of the rational. */ public int getNumerator() { + if (mDenominator == 0) { + return 0; + } return mNumerator; } @@ -65,22 +63,41 @@ public final class Rational { return mDenominator; } + private boolean isNaN() { + return mDenominator == 0 && mNumerator == 0; + } + + private boolean isInf() { + return mDenominator == 0 && mNumerator > 0; + } + + private boolean isNegInf() { + return mDenominator == 0 && mNumerator < 0; + } + /** *Compare this Rational to another object and see if they are equal.
* *A Rational object can only be equal to another Rational object (comparing against any other * type will return false).
* - *A Rational object is considered equal to another Rational object if and only if their - * reduced forms have the same numerator and denominator.
+ *A Rational object is considered equal to another Rational object if and only if one of + * the following holds
: + *A reduced form of a Rational is calculated by dividing both the numerator and the * denominator by their greatest common divisor.
* *
- * (new Rational(1, 2)).equals(new Rational(1, 2)) == true // trivially true
- * (new Rational(2, 3)).equals(new Rational(1, 2)) == false // trivially false
- * (new Rational(1, 2)).equals(new Rational(2, 4)) == true // true after reduction
+ * (new Rational(1, 2)).equals(new Rational(1, 2)) == true // trivially true
+ * (new Rational(2, 3)).equals(new Rational(1, 2)) == false // trivially false
+ * (new Rational(1, 2)).equals(new Rational(2, 4)) == true // true after reduction
+ * (new Rational(0, 0)).equals(new Rational(0, 0)) == true // NaN.equals(NaN)
+ * (new Rational(1, 0)).equals(new Rational(5, 0)) == true // both are +infinity
+ * (new Rational(1, 0)).equals(new Rational(-1, 0)) == false // +infinity != -infinity
*
*
* @param obj a reference to another object
@@ -91,13 +108,17 @@ public final class Rational {
public boolean equals(Object obj) {
if (obj == null) {
return false;
- }
- if (this == obj) {
- return true;
- }
- if (obj instanceof Rational) {
+ } else if (obj instanceof Rational) {
Rational other = (Rational) obj;
- if(mNumerator == other.mNumerator && mDenominator == other.mDenominator) {
+ if (mDenominator == 0 || other.mDenominator == 0) {
+ if (isNaN() && other.isNaN()) {
+ return true;
+ } else if (isInf() && other.isInf() || isNegInf() && other.isNegInf()) {
+ return true;
+ } else {
+ return false;
+ }
+ } else if (mNumerator == other.mNumerator && mDenominator == other.mDenominator) {
return true;
} else {
int thisGcd = gcd();
@@ -117,7 +138,25 @@ public final class Rational {
@Override
public String toString() {
- return mNumerator + "/" + mDenominator;
+ if (isNaN()) {
+ return "NaN";
+ } else if (isInf()) {
+ return "Infinity";
+ } else if (isNegInf()) {
+ return "-Infinity";
+ } else {
+ return mNumerator + "/" + mDenominator;
+ }
+ }
+
+ /**
+ * Convert to a floating point representation.
+ * + * @return The floating point representation of this rational number. + * @hide + */ + public float toFloat() { + return (float) mNumerator / (float) mDenominator; } @Override diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java index 926719c691a11..9621f92b78f53 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java @@ -50,12 +50,20 @@ public class RationalTest extends junit.framework.TestCase { assertEquals(1, r.getNumerator()); assertEquals(2, r.getDenominator()); - // Dividing by zero is not allowed - try { - r = new Rational(1, 0); - fail("Expected Rational constructor to throw an IllegalArgumentException"); - } catch(IllegalArgumentException e) { - } + // Infinity. + r = new Rational(1, 0); + assertEquals(0, r.getNumerator()); + assertEquals(0, r.getDenominator()); + + // Negative infinity. + r = new Rational(-1, 0); + assertEquals(0, r.getNumerator()); + assertEquals(0, r.getDenominator()); + + // NaN. + r = new Rational(0, 0); + assertEquals(0, r.getNumerator()); + assertEquals(0, r.getDenominator()); } @SmallTest @@ -110,5 +118,34 @@ public class RationalTest extends junit.framework.TestCase { assertEquals(moreComplicated, moreComplicated2); assertEquals(moreComplicated2, moreComplicated); + Rational nan = new Rational(0, 0); + Rational nan2 = new Rational(0, 0); + assertTrue(nan.equals(nan)); + assertTrue(nan.equals(nan2)); + assertTrue(nan2.equals(nan)); + assertFalse(nan.equals(r)); + assertFalse(r.equals(nan)); + + // Infinities of the same sign are equal. + Rational posInf = new Rational(1, 0); + Rational posInf2 = new Rational(2, 0); + Rational negInf = new Rational(-1, 0); + Rational negInf2 = new Rational(-2, 0); + assertEquals(posInf, posInf); + assertEquals(negInf, negInf); + assertEquals(posInf, posInf2); + assertEquals(negInf, negInf2); + + // Infinities aren't equal to anything else. + assertFalse(posInf.equals(negInf)); + assertFalse(negInf.equals(posInf)); + assertFalse(negInf.equals(r)); + assertFalse(posInf.equals(r)); + assertFalse(r.equals(negInf)); + assertFalse(r.equals(posInf)); + assertFalse(posInf.equals(nan)); + assertFalse(negInf.equals(nan)); + assertFalse(nan.equals(posInf)); + assertFalse(nan.equals(negInf)); } -} \ No newline at end of file +}