# Minor Change Proposal for Class 'Numeric'

**URL:** <https://www.ruby-forum.com/t/minor-change-proposal-for-class-numeric/82980>\
**Category:** Ruby\
**Created:** [January 22, 2007, 9:50pm UTC](https://www.ruby-forum.com/t/minor-change-proposal-for-class-numeric/82980 "2007-01-22T21:50:42Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![wonado](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/919ad9/32.png) [@wonado](https://www.ruby-forum.com/u/wonado)\
**Post date:** [January 22, 2007, 9:50pm UTC](https://www.ruby-forum.com/t/minor-change-proposal-for-class-numeric/82980/1 "2007-01-22T21:50:42Z")

</div>

Hi!

I didn’t find there a discussion about this here, so first a description  
of this  
(very) minor change proposal.

I miss the “Sign function” in class “Numeric”.

It can simply be added by something like…

class Numeric  
def sign  
self\<0?-1:self\>0?1:0  
end  
end

…but it should be much faster if be defined in the original class.

This method will be used in several algorithms, so it should be  
available from  
my point of view.

Wolfgang Nádasi-Donner

---

<div class="post-metadata">

**Author:** ![wonado](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/919ad9/32.png) [@wonado](https://www.ruby-forum.com/u/wonado)\
**Post date:** [January 22, 2007, 9:54pm UTC](https://www.ruby-forum.com/t/minor-change-proposal-for-class-numeric/82980/2 "2007-01-22T21:54:42Z")

</div>

Wolfgang Nádasi-Donner wrote:

> def sign  
> self\<0?-1:self\>0?1:0  
> end  
> end
> 
> …but it should be much faster if be defined in the original class.
> 
> This method will be used in several algorithms, so it should be  
> available from my point of view.

Seconded.

Vince

---

<div class="post-metadata">

**Author:** ![wonado](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/919ad9/32.png) [@wonado](https://www.ruby-forum.com/u/wonado)\
**Post date:** [January 23, 2007, 12:16am UTC](https://www.ruby-forum.com/t/minor-change-proposal-for-class-numeric/82980/3 "2007-01-23T00:16:16Z")

</div>

Wolfgang Nádasi-Donner wrote:

> class Numeric  
> def sign  
> self\<0?-1:self\>0?1:0  
> end  
> end
> 
> …but it should be much faster if be defined in the original class.

a) Why do you need it to be so fast? Two comparisons seems pretty  
lightweight to me!  
b) Why do you think it’s generally useful? I think such a method would  
have helped me only once or twice in all my programming years.

c) You can implement that more compactly (if not more efficiently) as:

irb(main):001:0\> class Numeric; def sign; self \<=\> 0; end; end  
=\> nil  
irb(main):002:0\> -1.sign  
=\> -1  
irb(main):003:0\> -5.sign  
=\> -1  
irb(main):004:0\> 0.sign  
=\> 0  
irb(main):005:0\> 3.sign  
=\> 1

---

<div class="post-metadata">

**Author:** ![wonado](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/919ad9/32.png) [@wonado](https://www.ruby-forum.com/u/wonado)\
**Post date:** [January 23, 2007, 12:45am UTC](https://www.ruby-forum.com/t/minor-change-proposal-for-class-numeric/82980/4 "2007-01-23T00:45:20Z")

</div>

On Jan 22, 2007, at 15:18, Vincent F. wrote:

> > a) Why do you need it to be so fast? Two comparisons seems pretty  
> > lightweight to me!
> 
> You forget function lookup: there is three function lookup for this  
> code. Hardcoded in C is way faster (with only one function lookup).

So you’ve benchmarked it and found that calling Numeric#sign takes up  
a significant part of your runtime?

Note that you can write this in C for about 5 extra lines using  
RubyInline.

–  
Eric H. - removed\_email\_address@domain.invalid - [http://blog.segment7.net](http://blog.segment7.net)

I LIT YOUR GEM ON FIRE!

---

<div class="post-metadata">

**Author:** ![wonado](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/919ad9/32.png) [@wonado](https://www.ruby-forum.com/u/wonado)\
**Post date:** [January 23, 2007, 12:53am UTC](https://www.ruby-forum.com/t/minor-change-proposal-for-class-numeric/82980/5 "2007-01-23T00:53:21Z")

</div>

Eric H. wrote:

> > You forget function lookup: there is three function lookup for this  
> > code. Hardcoded in C is way faster (with only one function lookup).
> 
> So you’ve benchmarked it and found that calling Numeric#sign takes up a  
> significant part of your runtime?

No 😉 I just point out that a C implementation will be faster than a  
pure Ruby one. Then, if you rely heavily on it, well, it would count,  
wouldn’t it ?

But I mainly raised the point to provoke, I obviously got what I  
wanted, didn’t I 😉

> Note that you can write this in C for about 5 extra lines using  
> RubyInline.

That definitely is a good idea !

Cheers,

Vince

---

<div class="post-metadata">

**Author:** ![wonado](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/919ad9/32.png) [@wonado](https://www.ruby-forum.com/u/wonado)\
**Post date:** [January 23, 2007, 12:19am UTC](https://www.ruby-forum.com/t/minor-change-proposal-for-class-numeric/82980/6 "2007-01-23T00:19:16Z")

</div>

Phrogz wrote:

> lightweight to me!  
> You forget function lookup: there is three function lookup for this  
> code. Hardcoded in C is way faster (with only one function lookup).

Vince

---

<div class="post-metadata">

**Author:** ![wonado](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/919ad9/32.png) [@wonado](https://www.ruby-forum.com/u/wonado)\
**Post date:** [January 23, 2007, 1:10am UTC](https://www.ruby-forum.com/t/minor-change-proposal-for-class-numeric/82980/7 "2007-01-23T01:10:24Z")

</div>

Phrogz schrieb:

> b) Why do you think it’s generally useful? I think such a method would  
> have helped me only once or twice in all my programming years.

There is only one reason: It is a standard function used in mathematics  
and  
nearly everybody knows a function names “sign” or “sgn” from other  
programming  
languages.

I think that the code for this method is still there in the kernel.

> c) You can implement that more compactly (if not more efficiently) as:
> 
> irb(main):001:0\> class Numeric; def sign; self \<=\> 0; end; end

It was only an example to describe what I mean. I have no suggestions  
for an  
implementation in the Ruby kernel.

I only think, that a mathematical standard function should be available.

Wolfgang Nádasi-Donner

---

<div class="post-metadata">

**Author:** ![wonado](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/919ad9/32.png) [@wonado](https://www.ruby-forum.com/u/wonado)\
**Post date:** [January 23, 2007, 12:56am UTC](https://www.ruby-forum.com/t/minor-change-proposal-for-class-numeric/82980/8 "2007-01-23T00:56:22Z")

</div>

Vincent F. wrote:

> > a) Why do you need it to be so fast? Two comparisons seems pretty  
> > lightweight to me!
> 
> You forget function lookup: there is three function lookup for this  
> code. Hardcoded in C is way faster (with only one function lookup).

I actually hadn’t forgotten it, but (mistakenly) thought that \< and \>  
didn’t have normal method overhead. So, the spaceship operator is  
actually more terse and faster:

class Numeric  
def sign1; self \< 1 ? -1 : self \> 1 ? 1 : 0; end  
def sign2; self\<=\>0; end  
def sign3; 0; end  
end

require ‘benchmark’

N = 1\_000\_000  
Benchmark.bmbm{ |x|  
x.report{  
N.times{ -5.sign1; 5.sign1; 0.sign1 }  
}  
x.report{  
N.times{ -5.sign2; 5.sign2; 0.sign2 }  
}  
x.report{  
N.times{ -5.sign3; 5.sign3; 0.sign3 }  
}  
x.report{  
N.times{ -5.abs; 5.abs; 0.abs }  
}  
}

Rehearsal ------------------------------------  
3.391000 0.000000 3.391000 ( 3.421000)  
2.296000 0.000000 2.296000 ( 2.313000)  
1.610000 0.000000 1.610000 ( 1.609000)  
0.969000 0.000000 0.969000 ( 0.969000)  
--------------------------- total: 8.266000sec

```
   user system total real

```

2.781000 0.000000 2.781000 ( 2.797000)  
2.250000 0.000000 2.250000 ( 2.249000)  
1.547000 0.000000 1.547000 ( 1.547000)  
0.922000 0.000000 0.922000 ( 0.922000)

So, if we assume that it would be about as fast as #abs, then you’re  
talking about saving about 1.3 MICRO seconds per call (on a 3GHz P4). I  
would be surprised (and interested) if saving that amount of time made  
a difference in someone’s application, for this particular method.

To put it in perspective:  
Suppose your Ruby program were controlling a game or simulation.  
Suppose you were getting 30fps. Suppose you were calling this method  
10,000 times PER FRAME. The difference between having this method  
rewritten in the core and using the spaceship operator gets you all the  
way to…30.9fps.
