Permalink
Browse files

add unit tests, improve handling of conversions from doubles

  • Loading branch information...
1 parent c70a238 commit 85261535939ed62a10159b2ae4b83d47654e4e08 @sanity committed Nov 6, 2012
@@ -1,13 +0,0 @@
-<component name="libraryTable">
- <library name="Maven: junit:junit:3.8.1">
- <CLASSES>
- <root url="jar://$MAVEN_REPOSITORY$/junit/junit/3.8.1/junit-3.8.1.jar!/" />
- </CLASSES>
- <JAVADOC>
- <root url="jar://$MAVEN_REPOSITORY$/junit/junit/3.8.1/junit-3.8.1-javadoc.jar!/" />
- </JAVADOC>
- <SOURCES>
- <root url="jar://$MAVEN_REPOSITORY$/junit/junit/3.8.1/junit-3.8.1-sources.jar!/" />
- </SOURCES>
- </library>
-</component>
@@ -0,0 +1,13 @@
+<component name="libraryTable">
+ <library name="Maven: junit:junit:4.10">
+ <CLASSES>
+ <root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.10/junit-4.10.jar!/" />
+ </CLASSES>
+ <JAVADOC>
+ <root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.10/junit-4.10-javadoc.jar!/" />
+ </JAVADOC>
+ <SOURCES>
+ <root url="jar://$MAVEN_REPOSITORY$/junit/junit/4.10/junit-4.10-sources.jar!/" />
+ </SOURCES>
+ </library>
+</component>
@@ -0,0 +1,13 @@
+<component name="libraryTable">
+ <library name="Maven: org.hamcrest:hamcrest-core:1.1">
+ <CLASSES>
+ <root url="jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar!/" />
+ </CLASSES>
+ <JAVADOC>
+ <root url="jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1-javadoc.jar!/" />
+ </JAVADOC>
+ <SOURCES>
+ <root url="jar://$MAVEN_REPOSITORY$/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1-sources.jar!/" />
+ </SOURCES>
+ </library>
+</component>
View
Oops, something went wrong.
View
@@ -10,7 +10,8 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="library" scope="TEST" name="Maven: junit:junit:3.8.1" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.10" level="project" />
+ <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib:0.1.3395" level="project" />
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-runtime:0.1.3395" level="project" />
</component>
View
@@ -31,9 +31,9 @@
<dependencies>
<dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.1</version>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
@@ -22,29 +22,48 @@ fun Rational(str: String): Rational {
return Rational(java.lang.Long.parseLong(raw), pow10((str.length - dpIx).toLong()))
}
-fun Rational(number : Number) : Rational =
- when (number) {
- is Int -> Rational(number.toLong(), 1)
- is Long -> Rational(number, 1)
- is Rational -> number
- else -> {
- // TODO: Make more efficient, should probably pull the double apart using Double.doubleToLongBits
- if (number is Double) {
- require (!java.lang.Double.isInfinite(number.toDouble()) && !java.lang.Double.isNaN(number.toDouble()))
+fun Rational(number: Number): Rational =
+ when (number) {
+ is Int -> Rational(number.toLong(), 1)
+ is Long -> Rational(number, 1)
+ is Rational -> number
+ else -> {
+ if (number is Double || number is Float) {
+ require (!java.lang.Double.isInfinite(number.toDouble()) && !java.lang.Double.isNaN(number.toDouble()))
+ }
+ // Stolen from http://goo.gl/4oXPj
+ val numberAsDouble = number.toDouble()
+ val bits = java.lang.Double.doubleToLongBits(numberAsDouble)
+ val sign = bits.ushr(63).toLong()
+ val exponent = (((bits.ushr(52)) xor (sign shl 11)) - 1023).toLong()
+ val fraction = (bits shl 12).toLong()
+ var a = 1.toLong()
+ var b = 1.toLong()
+ var i = 63
+ while (i >= 12) {
+ a = a * 2.toLong() + ((fraction.ushr(i)) and 1)
+ b *= 2.toLong()
+ i--
+ }
+ if (exponent > 0)
+ a *= 1 shl exponent.toInt()
+ else
+ b *= 1 shl -exponent.toInt()
+ if (sign == 1.toLong())
+ a *= -1
+ Rational(a, b)
}
- Rational(number.toDouble().toString())
}
- }
fun gcf(a: Long, b: Long): Long = if (b == 0.toLong()) a else gcf(b, a % b)
public fun Rational.minus(): Rational = Rational(-numerator, denominator)
public fun Rational.plus(): Rational = this
-public fun Number.plus(r: Rational) : Rational = r + Rational(this)
-public fun Number.minus(r: Rational) : Rational = r - Rational(this)
-public fun Number.times(r: Rational) : Rational = r * Rational(this)
-public fun Number.div(r: Rational) : Rational = r / Rational(this)
+public fun Number.plus(r: Rational): Rational = r + Rational(this)
+public fun Number.minus(r: Rational): Rational = r - Rational(this)
+public fun Number.times(r: Rational): Rational = r * Rational(this)
+public fun Number.div(r: Rational): Rational = r / Rational(this)
private fun pow10(var exp: Long): Long {
var result: Long = 1
@@ -57,9 +76,10 @@ private fun pow10(var exp: Long): Long {
return result
}
-class Rational(num: Long, denom: Long): Number() {
- val numerator : Long
- val denominator : Long
+class Rational(num: Long, denom: Long): Number(), Comparable<Rational> {
+
+ val numerator: Long
+ val denominator: Long
{
require (denom != 0.toLong())
val absNum = Math.abs(num);
@@ -79,6 +99,13 @@ class Rational(num: Long, denom: Long): Number() {
return false
}
}
+
+ public override fun compareTo(other: Rational): Int {
+ val mNum = numerator * other.denominator;
+ val oNum = other.numerator * denominator;
+ return mNum.compareTo(oNum)
+ }
+
public override fun toFloat(): Float = numerator.toFloat() / denominator.toFloat()
public override fun toLong(): Long = numerator / denominator
@@ -93,25 +120,25 @@ class Rational(num: Long, denom: Long): Number() {
public override fun toDouble(): Double = numerator.toDouble() / denominator.toDouble()
- public fun minus(other : Rational): Rational {
+ public fun minus(other: Rational): Rational {
val mn = numerator * other.denominator
val md = other.numerator * denominator
return Rational(mn - md, denominator * other.denominator)
}
- public fun plus(other : Rational): Rational {
+ public fun plus(other: Rational): Rational {
val mn = numerator * other.denominator
val md = other.numerator * denominator
return Rational(mn + md, denominator * other.denominator)
}
- public fun times(other: Long) : Rational = Rational(numerator * other, denominator * other)
+ public fun times(other: Long): Rational = Rational(numerator * other, denominator * other)
public fun times(other: Rational): Rational = Rational(numerator * other.numerator, denominator * other.denominator)
public fun div(other: Rational): Rational = Rational(numerator * other.denominator, denominator * other.numerator)
public fun plus(): Rational = this
- public fun toString() : String = if (denominator != 1.toLong()) "($numerator/$denominator)" else "$numerator"
+ public fun toString(): String = if (denominator != 1.toLong()) "($numerator/$denominator)" else "$numerator"
}
@@ -0,0 +1,46 @@
+package rational
+
+import org.junit.Test
+import kotlin.test.*
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: ian
+ * Date: 11/6/12
+ * Time: 8:08 AM
+ * To change this template use File | Settings | File Templates.
+ */
+
+class RationalTest {
+ Test fun add2RationalsTest() {
+ expect (Rational(3, 4)) {
+ Rational(1, 2) + Rational(1, 4)
+ }
+ }
+
+ Test fun subtract2RationalsTest() {
+ expect (Rational(3, 4)) {
+ Rational(1, 1) - Rational(1, 4)
+ }
+ }
+
+ Test fun multiply2RationalsTest() {
+ expect (Rational(1, 4)) {
+ Rational(1, 2) * Rational(1, 2)
+ }
+ }
+
+ Test fun divide2RationalsTest() {
+ expect (Rational(1, 4)) {
+ Rational(1, 2) / Rational(2, 1)
+ }
+ }
+
+ Test fun simplifyTest() {
+ expect (Rational(1, 2)) {Rational(2, 4)}
+ }
+
+ Test fun doubleConvertTest() {
+ expect (Rational(1, 2)) {Rational(0.5)}
+ }
+}
@@ -1,38 +0,0 @@
-package us.rational;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * Unit test for simple App.
- */
-public class AppTest
- extends TestCase
-{
- /**
- * Create the test case
- *
- * @param testName name of the test case
- */
- public AppTest( String testName )
- {
- super( testName );
- }
-
- /**
- * @return the suite of tests being tested
- */
- public static Test suite()
- {
- return new TestSuite( AppTest.class );
- }
-
- /**
- * Rigourous Test :-)
- */
- public void testApp()
- {
- assertTrue( true );
- }
-}

0 comments on commit 8526153

Please sign in to comment.