# Re: C-Style Ints (#85) - not a spoiler, a test harness

**URL:** <https://www.ruby-forum.com/t/re-c-style-ints-85-not-a-spoiler-a-test-harness/96722>\
**Category:** Ruby\
**Created:** [July 1, 2006, 2:29am UTC](https://www.ruby-forum.com/t/re-c-style-ints-85-not-a-spoiler-a-test-harness/96722 "2006-07-01T02:29:34Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![johnnybutler7](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johnnybutler7](https://www.ruby-forum.com/u/johnnybutler7)\
**Post date:** [July 1, 2006, 2:29am UTC](https://www.ruby-forum.com/t/re-c-style-ints-85-not-a-spoiler-a-test-harness/96722/1 "2006-07-01T02:29:34Z")

</div>

Given the number of edge conditions for this quiz it seemed like a good  
place for a test harness. Here is the irb session in the quiz  
translated to  
a test harness. It is my first use of the test framework so hopefully I  
haven’t made any horrible errors. Just put this in the file quiz85.rb  
and  
then use “ruby quiz85.rb” to test for correctness (it works better from  
the  
command line than from irb - I don’t know why but someone here does).  
Have  
fun!

# test harness for ruby quiz 85

# see it at:

# [Ruby Quiz - C-Style Ints (#85)](http://www.rubyquiz.com/quiz85.html)

require ‘test/unit’  
require ‘UnsignedFixedWidthInt.rb’  
require ‘SignedFixedWidthInt.rb’

class TestUnsignedFixedWidthInt \< Test::Unit::TestCase  
def test\_quiz\_example\_unsigned  
n = UnsignedFixedWidthInt.new(0xFF, 8)  
assert\_equal( n, 255 )  
n += 2  
assert\_equal( n, 1 )  
n = n \<\< 1  
assert\_equal( n, 2 )  
n = n \>\> 1  
assert\_equal( n, 1 )  
assert\_equal( ~n, 254 )  
n += 12  
assert\_equal( n, 13 )  
n = n & 0x0E  
assert\_equal( n, 12 )  
end  
def test\_quiz\_example\_too\_wide  
n = UnsignedFixedWidthInt.new(0x0, 8)  
assert\_equal( n, 0 )  
n += 0xFFEE  
assert\_equal( n, 238 )  
end  
end

class TestUnsignedFixedWidthInt \< Test::Unit::TestCase  
def test\_quiz\_example\_signed  
n = SignedFixedWidthInt.new(0x01, 8)  
assert\_equal( n, 1 )  
n = n \<\< 7  
assert\_equal( n, -128 )  
n -= 1  
assert\_equal( n, 127 )  
n = n \>\> 6  
assert\_equal( n, 1 )  
n -= 2  
assert\_equal( n, -1 )  
n = n ^ 0xF3  
assert\_equal( n, 12 )  
n = n | 0x01  
assert\_equal( n, 13 )  
end  
end

---

<div class="post-metadata">

**Author:** ![johnnybutler7](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johnnybutler7](https://www.ruby-forum.com/u/johnnybutler7)\
**Post date:** [July 1, 2006, 2:14pm UTC](https://www.ruby-forum.com/t/re-c-style-ints-85-not-a-spoiler-a-test-harness/96722/2 "2006-07-01T14:14:41Z")

</div>

On 7/1/06, John B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Given the number of edge conditions for this quiz it seemed like a good  
> place for a test harness. Here is the irb session in the quiz translated to  
> a test harness. It is my first use of the test framework so hopefully I  
> haven’t made any horrible errors.

Good idea, here are the tests i’m using. It also includes the irb  
session as well as a number of other tests.  
It assumes the result of any calculation with FWI’s and integers is a  
FWI.  
I’m using a different syntax for the FWI’s, but it should be easy  
enough to convert this to whatever you’re using.

Gmail will probably mess up my indent again, so here’s a rafb link as  
well:  
[http://rafb.net/paste/results/rwO1Kf64.html](http://rafb.net/paste/results/rwO1Kf64.html)

class FWITest \< Test::Unit::TestCase  
def test\_unsigned\_8  
uint8 = UnsignedFWI(8)  
n=uint8.new(0xFF)  
assert\_equal(255 , n)  
n += 2  
assert\_equal(1 , n)  
n = n \<\< 1  
assert\_equal(2 , n)  
n = n \>\> 1  
assert\_equal(1 , n)  
assert\_equal(254 , ~n)  
n += 12  
assert\_equal(13 , n)  
n = n & 0x0E  
assert\_equal(12 , n)  
n -= 13  
assert\_equal(255 , n)  
end

def test\_signed\_8  
int8 = SignedFWI(8)  
n = int8.new(1)  
assert\_equal(n,1)  
n = n \<\< 7  
assert\_equal(-128 , n)  
n -= 1  
assert\_equal(127 , n)  
n = n \>\> 6  
assert\_equal(1 , n)  
n -= 2  
assert\_equal(-1 , n)  
n = n ^ 0xF3  
assert\_equal(12 , n)  
n = n | 0x01  
assert\_equal(13 , n)  
end

def test\_too\_wide  
uint8 = UnsignedFWI(8)  
assert\_equal(238, uint8.new(0) + 0xFFEE)  
end

def test\_short\_length\_unsigned  
uint3 = UnsignedFWI(3)  
uint10 = UnsignedFWI(10)  
n = uint3.new(8)  
assert\_equal(0, n)  
n -= 7  
assert\_equal(1, n)  
assert\_equal(0, n\*\*23 + 7)  
m = uint3.new(8)  
assert\_equal(1, n + m)  
assert\_equal(1, m + n)  
assert\_equal(1, 8 + n)  
l = uint10.new(11)  
assert\_equal(1100-1024, l_100)  
assert\_equal(1100-1024, 100_l)  
end

def test\_short\_length\_signed  
int3 = SignedFWI(3)  
n = int3.new(4)  
assert\_equal(-4, n)  
assert\_equal(3 , (+n)-1)  
assert\_equal(n , 8+n)  
assert\_equal(-n, n)  
n -= 1  
assert\_equal(3 , n)  
end

def test\_long\_length\_signed  
int76 = SignedFWI(76)  
n = int76.new( 1\<\<75 )  
assert\_equal(-(1\<\<75) , n)  
n -= 1  
assert\_equal((1\<\<75)-1 , n)  
n = int76.new(2)  
n \*= (1\<\<75)-1  
assert\_equal(-2 , n)  
end

def test\_power  
uint3 = UnsignedFWI(3)  
assert\_equal(2, 2 \*\* uint3.new(1))  
assert\_equal(0, 2 \*\* uint3.new(3))  
assert\_equal(0, 2 \*\* uint3.new(67))  
assert\_equal(1, 3 \*\* uint3.new(2))  
assert\_equal(3, uint3.new(3) \*\* uint3.new(-1)) # 3\*\*7 mod 8  
end  
end

---

<div class="post-metadata">

**Author:** ![johnnybutler7](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johnnybutler7](https://www.ruby-forum.com/u/johnnybutler7)\
**Post date:** [July 2, 2006, 2:40am UTC](https://www.ruby-forum.com/t/re-c-style-ints-85-not-a-spoiler-a-test-harness/96722/3 "2006-07-02T02:40:56Z")

</div>

“Sander L.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

> Good idea, here are the tests i’m using. It also includes the irb  
> session as well as a number of other tests.  
> It assumes the result of any calculation with FWI’s and integers is a FWI.  
> I’m using a different syntax for the FWI’s, but it should be easy  
> enough to convert this to whatever you’re using.

I like this syntax though better than the one in the quiz and may  
adopt it. Actually, it shouldn’t be too hard to support both  
syntaxes…

I do take issue with one of your tests, though:

> def test\_power  
> uint3 = UnsignedFWI(3)  
> assert\_equal(2, 2 \*\* uint3.new(1))  
> assert\_equal(0, 2 \*\* uint3.new(3))  
> assert\_equal(0, 2 \*\* uint3.new(67))  
> assert\_equal(1, 3 \*\* uint3.new(2))  
> assert\_equal(3, uint3.new(3) \*\* uint3.new(-1)) # 3\*\*7 mod 8  
> end

That just feels wrong. (except for the last one) I would write:

def test\_power  
uint3 = UnsignedFWI(3)  
assert\_equal(2, uint3.new(2) \*\* 1)  
assert\_equal(0, uint3.new(2) \*\* 3)  
assert\_equal(0, uint3.new(2) \*\* 67)  
assert\_equal(1, uint3.new(3) \*\* 2)  
assert\_equal(3, uint3.new(3) \*\* uint3.new(-1)) # 3\*\*7 mod 8  
end

And maybe:

def test\_power\_fwi\_exponent  
uint3 = UnsignedFWI(3)  
assert\_equal(2, 2 \*\* uint3.new(1))  
assert\_equal(8, 2 \*\* uint3.new(3))  
assert\_equal(8, 2 \*\* uint3.new(67))  
end

I really think that you want to keep exponentiation looking like  
repeated multiplication of the first argument.

Of course, it would be nice if our kind quiz host would respond with a  
few rulings for the edge cases I outlined before. At least then we’d  
know when we were ignoring the rules of the quiz.

---

<div class="post-metadata">

**Author:** ![johnnybutler7](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johnnybutler7](https://www.ruby-forum.com/u/johnnybutler7)\
**Post date:** [July 2, 2006, 2:44am UTC](https://www.ruby-forum.com/t/re-c-style-ints-85-not-a-spoiler-a-test-harness/96722/4 "2006-07-02T02:44:06Z")

</div>

Daniel M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

> Of course, it would be nice if our kind quiz host would respond with a  
> few rulings for the edge cases I outlined before. At least then we’d  
> know when we were ignoring the rules of the quiz.

And I see that he already did, so once again see that I should learn  
to read my entire mailbox before responding to anything.

---

<div class="post-metadata">

**Author:** ![johnnybutler7](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johnnybutler7](https://www.ruby-forum.com/u/johnnybutler7)\
**Post date:** [July 2, 2006, 10:57am UTC](https://www.ruby-forum.com/t/re-c-style-ints-85-not-a-spoiler-a-test-harness/96722/5 "2006-07-02T10:57:45Z")

</div>

On 7/2/06, Daniel M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I do take issue with one of your tests, though:  
> …  
> That just feels wrong. (except for the last one) I would write:  
> def test\_power  
> …  
> end

Agreed, the test put way too much focus on fixnum \*\* fwi.  
This was because my implementation first assumed any binary operation  
was commutative (it just switched both operands if the first was a  
fixnum), so 2 \*\* uint3.new(1) was uint3.new(1)\*\*2=1, and the test was  
there to help me fix this.

> And maybe:  
> assert\_equal(8, 2 \*\* uint3.new(67))  
> …  
> I really think that you want to keep exponentiation looking like  
> repeated multiplication of the first argument.

And i really think the result should be a fwi, for consistency with  
multiplication (‘repeated addition’).  
Anyway, in my implementation 2 \*\* uint3.new(67).to\_i == 8, so there’s  
still a way to get those calculations done as well.

---

<div class="post-metadata">

**Author:** ![johnnybutler7](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johnnybutler7](https://www.ruby-forum.com/u/johnnybutler7)\
**Post date:** [July 3, 2006, 5:12pm UTC](https://www.ruby-forum.com/t/re-c-style-ints-85-not-a-spoiler-a-test-harness/96722/6 "2006-07-03T17:12:14Z")

</div>

On Jul 1, 2006, at 7:39 PM, Daniel M. wrote:

> repeated multiplication of the first argument.  
> I think that’s a good point.

> Of course, it would be nice if our kind quiz host would respond with a  
> few rulings for the edge cases I outlined before. At least then we’d  
> know when we were ignoring the rules of the quiz.

The main rule: Do what you feel is right. If you explain why you  
make the choices you do and convince me you are right, I’ll talk  
about how clever you are in the summary. 😉

Sorry I wasn’t around this weekend. I felt it better to be hard to  
reach for a couple of days than to cancel this week’s quiz altogether.

James Edward G. II
