C-Style Ints (#85)

Hi,

here is my solution and some unit tests.

(I didn’t know that it’s possible to write a block with an array
argument,
as in “define_method meth do |*other|”. That’s a nice feature.)

Regards,
Boris

c_int.rb

class UnsignedFixedWidthInt

def initialize(value, bits)
raise ArgumentError.new(‘number of bits must be > 0’) if bits <= 0
@bits = bits
@value = value % 2**@bits
end

operators returning a new FixedWidthInt

%w{& ^ | << >> + - * / +@ -@ ~@}.each do |operator|
define_method operator do |*other|
self.class.new(@value.send(operator, *other), @bits)
end
end

methods forwarded to @value

%w{== < > <=> inspect to_s to_i to_int}.each do |meth|
define_method meth do |*other|
@value.send(meth, *other)
end
end

def coerce(other)
Integer == other ? [other, @value] : [Float(other), Float(@value)]
end
end

class SignedFixedWidthInt < UnsignedFixedWidthInt
def initialize(value, bits)
super(value, bits)
# value is negative if MSB is set:
@value -= 2**@bits if @value[@bits - 1] == 1
end
end

c_int_test.rb

require ‘c_int’
require ‘test/unit’

class CIntTest < Test::Unit::TestCase
def test_no_bits
assert_raises(ArgumentError) { UnsignedFixedWidthInt.new(0, 0) }
assert_raises(ArgumentError) { UnsignedFixedWidthInt.new(0, -1) }
end

def test_one_bit
n = UnsignedFixedWidthInt.new(0xFF, 1)
assert_equal 1, n

 n += 1
 assert_equal 0, n

 n = SignedFixedWidthInt.new(0xFF, 1)
 assert_equal(-1, n)

 n += 1
 assert_equal 0, n

 n += 1
 assert_equal(-1, n)

end

def test_unsigned
n = UnsignedFixedWidthInt.new(0xFF, 8)
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 = n * 24
 assert_equal 32, n

 n = n / 15
 assert_equal 2, n

end

def test_signed
n = SignedFixedWidthInt.new(0x01, 8)
assert_equal 1, n

 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

 n = +n
 assert_equal 13, n

 n = -n
 assert_equal(-13, n)

end

def test_too_wide
n = UnsignedFixedWidthInt.new(0x0, 8)
n += 0xFFEE
assert_equal 238, n
end

def test_signed_shift_right
n = SignedFixedWidthInt.new(0x80, 8)
n = n >> 1
assert_equal(-64, n) # with sign extension
end

def test_equal
s1 = SignedFixedWidthInt.new(-1, 4)
s2 = SignedFixedWidthInt.new(-1, 4)
s3 = SignedFixedWidthInt.new(1, 4)
u1 = UnsignedFixedWidthInt.new(1, 4)
u2 = UnsignedFixedWidthInt.new(1, 4)
assert u1 != s1
assert s1 != s3
assert u1 == u2
assert s1 == s2
assert s3 == u1
assert(-1 == s1)
assert s1 == -1
end

def test_conversions
n = SignedFixedWidthInt.new(-100, 7)
assert “-100”, n.to_s
assert “-100”, n.inspect
assert(-100, n.to_i)
assert(-100, n.to_int)
end

def test_coerce
n = UnsignedFixedWidthInt.new(1, 4)
assert 1.1 > n
assert 0.9 < n
assert 1 == n
end

def test_comparison
s = SignedFixedWidthInt.new(-1, 4)
u = UnsignedFixedWidthInt.new(1, 4)
assert u > s
assert s < u
assert s < 0
assert u > 0
assert 0 > s
assert 0 < u
assert_equal(-1, s <=> u)
assert_equal 1, u <=> s
assert_equal 0, 1 <=> u
assert_equal 0, -1 <=> s
end
end

At Mon, 3 Jul 2006 01:29:40 +0900, Dave B. wrote:

Here’s the code:

http://dave.burt.id.au/ruby/fixed_width_ints.rb

404s. Correction:

http://dave.burt.id.au/ruby/fixed_width_int.rb

Josef ‘Jupp’ Schugt

Hi!

At Mon, 3 Jul 2006 01:29:40 +0900, Dave B. wrote:

http://dave.burt.id.au/ruby/fixed_width_ints.rb
http://dave.burt.id.au/ruby/weak_hash.rb

The problem that the former URL is wrong turned my attention to the
question wether to post URLs that points to the Ruby code that one
assumes to be a solution to the Ruby Q. or to post the suggested
code.

My opinion is that one should post the code.

  • Posting the code is less error-prone simply because fewer sources
    of error are involved. No web server and browser is needed and in
    most cases mail user agents are superior to web servers and
    browsers as far as translation of one system’s encoding to another
    one’s is concerned. Solutions to the Ruby Q. don’t tend to be
    longer than ordinary e-mails so size is no reason not to use
    e-mail.

  • To my understanding, the reason of providing code is not primarily
    being listed as one of the people who contributed a solution. It is
    rather allowing others to comment on the code, point out mistakes,
    provide stylistic improvements, or even discuss if the solution
    actually fits the specification. This process is simplified by
    including the code in the mail so that it can easily be quoted.

  • Several mail user agents provide no easy way to open a URL. This
    usually means that one needs to copy it, perhaps start a Web
    browser, and then direct that browser to the given URL. The obvious
    question one may raise: Is that code acutally worth the effort? Theq
    likeliest answer is “No. If that guy were sure that he has written
    fantastic code, wouldn’t he be proud and show it to everyone in the
    most direct manner? Next mail, please.”

Just my 0.02 EUR.

Josef ‘Jupp’ Schugt

Jupp wrote:

My opinion is that one should post the code.

You have made a number of good points in support of that opinion.

I’ve attached the code I linked to (or tried to link to) earlier to this
mail.

Cheers,
Dave

On Jul 3, 2006, at 15:23, Dave B. wrote:

Jupp wrote:

My opinion is that one should post the code.

You have made a number of good points in support of that opinion.

I’ve attached the code I linked to (or tried to link to) earlier to
this
mail.

Not to be a trouble-maker, but attachments have a particular problem,
best illustrated by example:

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/199968

With code as short as this, simply including it inline in the message
body is likely the best way to share it most effectively.

matthew smillie.

On Mon, 3 Jul 2006, Josef ‘Jupp’ SCHUGT wrote:

  • To my understanding, the reason of providing code is not primarily
    likeliest answer is “No. If that guy were sure that he has written
    fantastic code, wouldn’t he be proud and show it to everyone in the
    most direct manner? Next mail, please.”
  • when all the code exists inline in the message one can search for
    it using
    google or gmane. this, to me, is by far the biggest advantage.

cheers.

-a

Sorry for the double-post, but I just thought I’d actually disagree with
part of Josef’s argument for in-line code over URLs.

Josef ‘Jupp’ SCHUGT wrote:

  • Posting the code is less error-prone simply because fewer sources
    of error are involved. No web server and browser is needed and in
    most cases mail user agents are superior to web servers and
    browsers as far as translation of one system’s encoding to another
    one’s is concerned. Solutions to the Ruby Q. don’t tend to be
    longer than ordinary e-mails so size is no reason not to use
    e-mail.

In my experience, the web browser is a far more consistent platform, and
perhaps more ubiquitous, too.

Solutions to the Ruby Q. are often longer than ordinary e-mails, and
anyway there was a problem with the (now-defunct) gateway interface that
often truncated Ruby Q. solutions. There are also the problems of
in-line code being re-formatted by mail agents; this is avoided by using
attachments rather than in-line code.

Your point stands, though – if you’re reading this message, you can
always read code that’s appended in-line.

  • To my understanding, the reason of providing code is not primarily
    being listed as one of the people who contributed a solution. It is
    rather allowing others to comment on the code, point out mistakes,
    provide stylistic improvements, or even discuss if the solution
    actually fits the specification. This process is simplified by
    including the code in the mail so that it can easily be quoted.

Absolutely.

  • Several mail user agents provide no easy way to open a URL. This
    usually means that one needs to copy it, perhaps start a Web
    browser, and then direct that browser to the given URL. The obvious
    question one may raise: Is that code acutally worth the effort? Theq
    likeliest answer is “No. If that guy were sure that he has written
    fantastic code, wouldn’t he be proud and show it to everyone in the
    most direct manner? Next mail, please.”

The fact that there are crappy mail clients (some even in common use)
seems to me to swing in favour of moving to the web. You can participate
on this list on the web; I’d recommend that over such a weak mail agent.

I always try and write the key features of my code, or why I think
people would want to read it, kind of like an executive summary (but
not). I like when people do this (with library announcements or whatever
else, too) because it not only helps the reader decide whether it’s
worth their time, but it also provides a “way in” to the code if they do
decide to look into it.

I think I’ve knocked down that point, so let me add another of my own:
if you put the code in the mail, it gets archived with the rest of the
list’s messages, and it does belong there. (You can download all
submitted solutions at rubyquiz.com, but that’s a bit out of the way
from the list.)

Just my 0.02 EUR.

Well, your 0.02 EUR is worth 1.7 times my 2 Aussie cents.

Cheers,
Dave

Matthew S. wrote:

Not to be a trouble-maker, but attachments have a particular problem,
best illustrated by example:

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/199968

With code as short as this, simply including it inline in the message
body is likely the best way to share it most effectively.

My mail agent is stupid for doing that to plain-text attachments.

It’s two files; that makes it harder to use from inside an email.
Identifying the files in the body text and copying and pasting those
snippets into appropriately named files is far less straightforward than
grabbing two files over HTTP.

I think I’m swinging back towards putting the stuff on the web again.

Cheers,
Dave

On Jul 3, 2006, at 9:43 AM, Dave B. wrote:

There are also the problems of
in-line code being re-formatted by mail agents; this is avoided by
using
attachments rather than in-line code.

This generally isn’t much of a problem if you keep your lines short,
which I believe is a good habit to get into anyway. I do try to
correct poorly wrapped lines when I pull the code out.

I always try and write the key features of my code, or why I think
people would want to read it, kind of like an executive summary (but
not). I like when people do this (with library announcements or
whatever
else, too) because it not only helps the reader decide whether it’s
worth their time, but it also provides a “way in” to the code if
they do
decide to look into it.

I love it when solvers do this, because it serves as the cliff-notes
for me when I am rescanning the solutions to write the summary, “Oh
yeah, I wanted to talk about that…”

James Edward G. II

On Jul 3, 2006, at 9:35 AM, [email protected] wrote:

assumes to be a solution to the Ruby Q. or to post the suggested
e-mail.
browser, and then direct that browser to the given URL. The obvious
question one may raise: Is that code acutally worth the effort?
Theq
likeliest answer is “No. If that guy were sure that he has written
fantastic code, wouldn’t he be proud and show it to everyone in the
most direct manner? Next mail, please.”

  • when all the code exists inline in the message one can search
    for it using
    google or gmane. this, to me, is by far the biggest advantage.

I agree that inlining solutions in the message is the best strategy.

That’s actually a little more work for me, because I have to dig them
out of the message, watch for file breaks, and try not to break name
associations for things like a test harness. Because of that, posts
that clearly delineate files and there names (where it matters) are
greatly appreciated. Here’s a good example from the solutions I just
put up:

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/199917

Still, I think inlining is best for the quizzes’s primary purpose,
for others to learn from, so I accept the extra work and still
believe it’s the way to go.

James Edward G. II

On Jun 30, 2006, at 7:57 PM, Daniel M. wrote:

I have some questions about some more edge cases.

I’ll give my two cents…

irb(main):005:0> ~n

Now, should we also try to ensure that (2 + n) has the same result as
(n + 2) ?

Sure, if you can manage it.

What happens when we operate on two FWIs at once? I would propose
that the answer should be that the result is a FWI with as many bits
as the larger of the two operands

Makes sense to me.

, but I’m stuck as to what to do when
you add a SignedFixedWidthInt to an UnsignedFixedWidthInt. What is
the result?

That is a tough call. I think I can come up with good arguments for
doing it two different ways, so I’m no help on this one.

I’d like to propose these rules of arithmetic:

Any operation between a FWI and a Float, Rational, or Complex has the
same result as though the FWI were replaced by an Integer of equal
value.

Makes sense to me.

property we might want to preserve when a is a FWI, even if “2” is
only a FWI with the value of “2”)

For ** (exponentiation), I’m not sure. My instinct is to say that
it’s an error to raise a FWI to a negative power, and that FWI **
FWI should produce the same type as the first argument. (Rationale:
it’s like repeated multiplication)

This alternate set of rules makes the most sense to me, but the only
“ruling” is what you think is best.

As for just taking the last n bits when passed an initial argument
that’s too wide - that’s exactly what you want to do. That lets us
emulate the C cast-to-smaller-type:

short int g = (short int) some_big_variable;

with FWI.new(). C is always taking only the least significant
portion, so if we want to look like C…

I buy that.

James Edward G. II

[email protected] wrote:

  • when all the code exists inline in the message one can search for it
    using
    google or gmane. this, to me, is by far the biggest advantage.

Google’s spider follows links. You’ll find all my linked-to quiz
submissions indexed separately on Google.

I suppose you meant searching Google G. or another archive of the
list, and I think that’s the only real benefit.

Cheers,
Dave

On Mon, 3 Jul 2006, James Edward G. II wrote:

Still, I think inlining is best for the quizzes’s primary purpose, for
others to learn from, so I accept the extra work and still believe it’s the
way to go.

hi james-

why not create a really simple form on the ruby quiz site for submitting
quizes? the form would allow a subject, short message, and uploaded
code or
tar.gz of code. i hate that kind of stuff but it could have real value
since
it could format a nice message for the list, enter the submission in db,
etc.
in short it could do everything you currently do by hand and,
considering
rubyquiz is a volunteer effort, i think people would be fine using a
form - so
long as it was mirrors to the list for the archives.

plus threading would actually work!

cheers.

-a

On Mon, 3 Jul 2006, Dave B. wrote:

In my experience, the web browser is a far more consistent platform, and
perhaps more ubiquitous, too.

nothing is ubiquitous like text and grep. all my mail is on disk -
because it
is i can use grep to search all of the archives. no mail agent compares
to
this. having the code as text means the plethora of text tools
available to
me also work on that code - it’s really hard to compare to this.

The fact that there are crappy mail clients (some even in common use) seems
to me to swing in favour of moving to the web. You can participate on this
list on the web; I’d recommend that over such a weak mail agent.

it’s not that they’re crappy - it’s that they are often remote. i use
pine or
mutt becuase i am logged in remotely 99.9% of the time to 10-50 machines
at
once. graphical mail browsers are totally out of the question to use
over
ssh, especially since i manage accounts for 4 different users and would
need a
window open for each. currently i keep all 4 open in a screen (the
screen
program in case you are un-aware) and can attach to this screen to
monitor my
mail from anywhere in the world on any platform using nothing but a
terminal
and ssh. you can imagaine that ‘popping open’ a url when i’m logged in
via
putty tunneling through a few linux boxes is slightly less than
convenient.

I think I’ve knocked down that point, so let me add another of my own: if
you put the code in the mail, it gets archived with the rest of the list’s
messages, and it does belong there. (You can download all submitted
solutions at rubyquiz.com, but that’s a bit out of the way from the list.)

and this is so important. the mailing list is a dynamic information
network with tools aplenty to navigate and search through it - but
pulling
information out we require new tools to be written in order to acheive
this.

that said - the odd url is fine with me, i simply prefer inlining.

kind regards.

-a

On Jul 3, 2006, at 10:30 AM, [email protected] wrote:

why not create a really simple form on the ruby quiz site for
submitting
quizes?

The main challenge then becomes getting people to use the form, I
suspect. :wink: However, it is planned for the Ruby Q. 2.0 site,
which is finally moving forward again after a long hibernation. Stay
tuned…

James Edward G. II

On Mon, 3 Jul 2006, Dave B. wrote:

[email protected] wrote:

  • when all the code exists inline in the message one can search for it
    using
    google or gmane. this, to me, is by far the biggest advantage.

Google’s spider follows links. You’ll find all my linked-to quiz
submissions indexed separately on Google.

I suppose you meant searching Google G. or another archive of the list,
and I think that’s the only real benefit.

right. but consider there are multiple ways of searching the archive -
for
instance i have it locally and use grep. grep does not follow links :wink:
on
the other hand it does allow me to do searches like

grep -A10 -B10 ‘Sync_m.synchronize’ ruby-talk/*

which would show me ten lines before and ten lines after every line in
the
archive with Sync_m.synchronize in it. that’s powerful. glimpse is
even
more useful but i digress…

cheers.

-a

On Tue, Jul 04, 2006 at 12:30:09AM +0900, [email protected] wrote:

why not create a really simple form on the ruby quiz site for submitting
quizes? the form would allow a subject, short message, and uploaded code or
tar.gz of code. i hate that kind of stuff but it could have real value
since it could format a nice message for the list, enter the submission in
db, etc. in short it could do everything you currently do by hand and,
considering rubyquiz is a volunteer effort, i think people would be fine
using a form - so long as it was mirrors to the list for the archives.

This is quite obvious, but…
shouldn’t the next 4-5 quizzes be used to implement such functionality?

On Tue, 4 Jul 2006, Mauricio F. wrote:

This is quite obvious, but… shouldn’t the next 4-5 quizzes be used to
implement such functionality?

you’ve obviously had more coffee than i today - that’s a great idea.
how
bout a script that allows posting quizes from the command line?

cheers.

-a

On Tue, 4 Jul 2006, James Edward G. II wrote:

The main challenge then becomes getting people to use the form, I suspect.
:wink:

shouldn’t be - simply tell people only quizes submitted via the form
will be
cataloged on the rubyquiz site.

However, it is planned for the Ruby Q. 2.0 site, which is finally
moving forward again after a long hibernation. Stay tuned…

great - keep up the fantastic work!

-a

On Mon, Jul 03, 2006 at 02:24:53AM +0900, Sander L. wrote:

Class.new(DelegateClass(Bignum)) {
This is very very nice. I was unsure if DelegateClass would work with
Bignum properly because of the Integer/Fixnum/Bignum hierarchy, so I
went for the forwardable interface straight away without even trying
this.

I believe this exhibits the same semantics in respect to coercion as
mine, in trying to preserve the type of the first argument. And it is
certainly shorter.

-Jürgen