[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

simple math question

Brad Tilley

10/25/2006 11:16:00 PM

What's the quickest way to determine if an int is an even number
2,4,6,8...
Anything such as int.even or int.odd returning true/false? I want to
test the length of an array and add one element to it if it has an odd
number of elements.

Thank you!

--
Posted via http://www.ruby-....

21 Answers

Bill Kelly

10/25/2006 11:21:00 PM

0

From: "Brad Tilley" <rtilley@vt.edu>
>
> What's the quickest way to determine if an int is an even number
> 2,4,6,8...
> Anything such as int.even or int.odd returning true/false? I want to
> test the length of an array and add one element to it if it has an odd
> number of elements.

class Integer
def even?
(self & 1) == 0
end
end


Hope this helps,

Bill



Rick DeNatale

10/25/2006 11:27:00 PM

0

On 10/25/06, Brad Tilley <rtilley@vt.edu> wrote:
> What's the quickest way to determine if an int is an even number
> 2,4,6,8...
> Anything such as int.even or int.odd returning true/false? I want to
> test the length of an array and add one element to it if it has an odd
> number of elements.
>
> Thank you!

Integer#[n] returns a 1 or 0 corresponding to bit n, with n=0 being
the least significant bit.

so

Even:
an_int[0].zero?

Odd:
an_int[0].nonzero?

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

Brad Tilley

10/25/2006 11:35:00 PM

0

Thanks for all the examples guys! Being Ruby, I thought there might be
some super simple method that just magically did this. I'll stick with
the old-fashioned modulo test.



--
Posted via http://www.ruby-....

Paul Lutus

10/26/2006 1:16:00 AM

0

Brad Tilley wrote:

> Thanks for all the examples guys! Being Ruby, I thought there might be
> some super simple method that just magically did this. I'll stick with
> the old-fashioned modulo test.

If speed matters, the modulo test is way slower than testing the LSB.

--
Paul Lutus
http://www.ara...

Jeff Schwab

10/26/2006 1:19:00 AM

0

Paul Lutus wrote:
> Brad Tilley wrote:
>
>> Thanks for all the examples guys! Being Ruby, I thought there might be
>> some super simple method that just magically did this. I'll stick with
>> the old-fashioned modulo test.
>
> If speed matters, the modulo test is way slower than testing the LSB.

Do you mean on a specific architecture, or is there a Ruby-specific
reason for one to be slower than the other?

Rick DeNatale

10/26/2006 1:56:00 AM

0

On 10/25/06, Jeffrey Schwab <jeff@schwabcenter.com> wrote:
> Paul Lutus wrote:
> > Brad Tilley wrote:
> >
> >> Thanks for all the examples guys! Being Ruby, I thought there might be
> >> some super simple method that just magically did this. I'll stick with
> >> the old-fashioned modulo test.
> >
> > If speed matters, the modulo test is way slower than testing the LSB.
>
> Do you mean on a specific architecture, or is there a Ruby-specific
> reason for one to be slower than the other?

Not really ruby-specific, and for the most part architecture independent.

Modulo basically involves an integer division operation, whereas bit
testing is a simple logical and with a mask.

(int & 1).zero? is probably faster than
int[0].zero?

Since the latter generates the mask using the bit position.

and both should be faster than

(int % 2).zero?

But it it's performance critical, benchmarking is recommended to
verify. One should never simply take 'rules of thumb' for granted.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

Ken Bloom

10/26/2006 4:02:00 AM

0

On Thu, 26 Oct 2006 01:19:08 +0000, Jeffrey Schwab wrote:

> Paul Lutus wrote:
>> Brad Tilley wrote:
>>
>>> Thanks for all the examples guys! Being Ruby, I thought there might be
>>> some super simple method that just magically did this. I'll stick with
>>> the old-fashioned modulo test.
>>
>> If speed matters, the modulo test is way slower than testing the LSB.
>
> Do you mean on a specific architecture, or is there a Ruby-specific
> reason for one to be slower than the other?

Modulo uses division hardware, which is slower than the hardware for
bitwise operations. Most C compilers know how to optimize this sort of
thing when it's known in advance that you're doing mod 2. I doubt Ruby's
that smart.

--Ken

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...
I've added a signing subkey to my GPG key. Please update your keyring.

Gavin Kistner

10/26/2006 4:13:00 AM

0

Rick DeNatale wrote:
> (int & 1).zero? is probably faster than
> int[0].zero?
>
> Since the latter generates the mask using the bit position.
>
> and both should be faster than
>
> (int % 2).zero?
>
> But it it's performance critical, benchmarking is recommended to
> verify. One should never simply take 'rules of thumb' for granted.

Let's just do it rather than speculating:

require 'benchmark'

ITERATIONS = 1_000_000
MAX_INT = 2 ** 30
NUMS = (1..ITERATIONS).map{ rand(MAX_INT) }
Benchmark.bmbm{ |x|
x.report '(n % 2).zero?' do
NUMS.each{ |n|
(n % 2).zero?
}
end

x.report 'n[0].zero?' do
NUMS.each{ |n|
n[0].zero?
}
end

x.report '(n & 1).zero?' do
NUMS.each{ |n|
(n & 1).zero?
}
end
}

#=> Rehearsal -------------------------------------------------
#=> (n % 2).zero? 2.060000 0.020000 2.080000 ( 2.244595)
#=> n[0].zero? 1.960000 0.010000 1.970000 ( 2.145238)
#=> (n & 1).zero? 1.990000 0.020000 2.010000 ( 2.275232)
#=> ---------------------------------------- total: 6.060000sec
#=>
#=> user system total real
#=> (n % 2).zero? 2.070000 0.010000 2.080000 ( 2.315105)
#=> n[0].zero? 1.960000 0.020000 1.980000 ( 2.143038)
#=> (n & 1).zero? 1.990000 0.010000 2.000000 ( 2.173120)

There is a very, very, very small difference in speed.

Paul Lutus

10/26/2006 6:21:00 AM

0

Phrogz wrote:

> Rick DeNatale wrote:
>> (int & 1).zero? is probably faster than
>> int[0].zero?
>>
>> Since the latter generates the mask using the bit position.
>>
>> and both should be faster than
>>
>> (int % 2).zero?
>>
>> But it it's performance critical, benchmarking is recommended to
>> verify. One should never simply take 'rules of thumb' for granted.
>
> Let's just do it rather than speculating:
>
> require 'benchmark'
>
> ITERATIONS = 1_000_000
> MAX_INT = 2 ** 30
> NUMS = (1..ITERATIONS).map{ rand(MAX_INT) }
> Benchmark.bmbm{ |x|
> x.report '(n % 2).zero?' do
> NUMS.each{ |n|
> (n % 2).zero?
> }
> end
>
> x.report 'n[0].zero?' do
> NUMS.each{ |n|
> n[0].zero?
> }
> end
>
> x.report '(n & 1).zero?' do
> NUMS.each{ |n|
> (n & 1).zero?
> }
> end
> }
>
> #=> Rehearsal -------------------------------------------------
> #=> (n % 2).zero? 2.060000 0.020000 2.080000 ( 2.244595)
> #=> n[0].zero? 1.960000 0.010000 1.970000 ( 2.145238)
> #=> (n & 1).zero? 1.990000 0.020000 2.010000 ( 2.275232)
> #=> ---------------------------------------- total: 6.060000sec
> #=>
> #=> user system total real
> #=> (n % 2).zero? 2.070000 0.010000 2.080000 ( 2.315105)
> #=> n[0].zero? 1.960000 0.020000 1.980000 ( 2.143038)
> #=> (n & 1).zero? 1.990000 0.010000 2.000000 ( 2.173120)
>
> There is a very, very, very small difference in speed.

I feel like Alice falling into the rabbit hole. I never thought I would see
the day when the difference between a division and a bit test would be
reduced to insignificance by other factors. Obviously I started thinking
about this (and developing my prejudices) before there were numeric
coprocessors.

Nice demonstration, BTW.

--
Paul Lutus
http://www.ara...

Jeff Schwab

10/26/2006 1:41:00 PM

0

Ken Bloom wrote:
> On Thu, 26 Oct 2006 01:19:08 +0000, Jeffrey Schwab wrote:
>
>> Paul Lutus wrote:
>>> Brad Tilley wrote:
>>>
>>>> Thanks for all the examples guys! Being Ruby, I thought there might be
>>>> some super simple method that just magically did this. I'll stick with
>>>> the old-fashioned modulo test.
>>> If speed matters, the modulo test is way slower than testing the LSB.
>> Do you mean on a specific architecture, or is there a Ruby-specific
>> reason for one to be slower than the other?
>
> Modulo uses division hardware, which is slower than the hardware for
> bitwise operations.

On what modern architecture? (I write x86 firmware.)