Why can a floating point number be used as an array index?

Discussion in 'Ruby' started by Jeff Dik, Mar 29, 2011.

  1. Jeff Dik

    Jeff Dik Guest

    Why can a floating point number be used as an array index? Anybody
    know of a good use case for this?

    irb(main):020:0> [1, 2, 3][0.3]
    1
    irb(main):021:0> [1, 2, 3][0.9]
    1

    Just curious,
    Jeff
    Jeff Dik, Mar 29, 2011
    #1
    1. Advertising

  2. Jeff Dik wrote in post #989828:
    > Why can a floating point number be used as an array index? Anybody
    > know of a good use case for this?
    >
    > irb(main):020:0> [1, 2, 3][0.3]
    > 1
    > irb(main):021:0> [1, 2, 3][0.9]
    > 1
    >
    > Just curious,
    > Jeff



    arr = [1,2,3,4....]
    arr[(anyhting).to_i]

    --
    Posted via http://www.ruby-forum.com/.
    Sniper Abandon, Mar 29, 2011
    #2
    1. Advertising

  3. Jeff Dik

    Sam Duncan Guest

    How about statistical bucketing. Imagine your indexes 1, 2, and 3 are Gb
    of RSS or something.

    > irb

    ruby-1.9.2-p0 > rss = [0.123, 1.223, 5.33, 2.294, 7.66, 5.6, 3.222,
    3.88, 3.44, 1.78] # incoming rss values
    => [0.123, 1.223, 5.33, 2.294, 7.66, 5.6, 3.222, 3.88, 3.44, 1.78]

    ruby-1.9.2-p0 > buckets = (0..rss.max).collect {|i| i} # bucket indexes
    => [0, 1, 2, 3, 4, 5, 6, 7]

    ruby-1.9.2-p0 > rss.reduce(Hash.new(0)) {|h, v| h.tap{|h|
    h[buckets[v]]+=1}} # statistics!
    => {0=>1, 1=>2, 5=>2, 2=>1, 7=>1, 3=>3}

    I'm sure there are lots of (probably simpler) ways to do the same thing,
    but it was a fun exercise nonetheless =]

    Sam


    On 30/03/11 07:35, Jeff Dik wrote:
    > Why can a floating point number be used as an array index? Anybody
    > know of a good use case for this?
    >
    > irb(main):020:0> [1, 2, 3][0.3]
    > 1
    > irb(main):021:0> [1, 2, 3][0.9]
    > 1
    >
    > Just curious,
    > Jeff
    >
    >
    Sam Duncan, Mar 29, 2011
    #3
  4. Keep in mind that arrays use the implicit integer conversion protocol, =
    #to_int, to make this conversion. You
    can't use any old object with #to_i:

    >> [1, 2, 3]["1"]

    TypeError: can't convert String into Integer

    Very few classes implement this protocol:

    >> ObjectSpace.each_object { |a| p(a) if Module =3D=3D=3D a && =

    a.instance_methods(false).include?:)to_int) }
    Float
    Integer
    Numeric

    I suspect the primary reason for allowing Arrays to convert floats to =
    appropriate indices is to simplify calculated array
    indices in *any* case. Sam gives a good example, but there are even more =
    common, simple cases where
    one might calculate array indices and not want to have to call #to_i =
    every time. Here's one for determining
    what item in a list was clicked:

    chosen_item =3D items[ pixel_clicked.y / item_size ]

    Michael Edgar

    http://carboni.ca/

    On Mar 29, 2011, at 4:17 PM, Sam Duncan wrote:

    > How about statistical bucketing. Imagine your indexes 1, 2, and 3 are =

    Gb of RSS or something.
    >=20
    > > irb

    > ruby-1.9.2-p0 > rss =3D [0.123, 1.223, 5.33, 2.294, 7.66, 5.6, 3.222, =

    3.88, 3.44, 1.78] # incoming rss values
    > =3D> [0.123, 1.223, 5.33, 2.294, 7.66, 5.6, 3.222, 3.88, 3.44, 1.78]
    >=20
    > ruby-1.9.2-p0 > buckets =3D (0..rss.max).collect {|i| i} # bucket =

    indexes
    > =3D> [0, 1, 2, 3, 4, 5, 6, 7]
    >=20
    > ruby-1.9.2-p0 > rss.reduce(Hash.new(0)) {|h, v| h.tap{|h| =

    h[buckets[v]]+=3D1}} # statistics!
    > =3D> {0=3D>1, 1=3D>2, 5=3D>2, 2=3D>1, 7=3D>1, 3=3D>3}
    >=20
    > I'm sure there are lots of (probably simpler) ways to do the same =

    thing, but it was a fun exercise nonetheless =3D]
    >=20
    > Sam
    >=20
    >=20
    > On 30/03/11 07:35, Jeff Dik wrote:
    >> Why can a floating point number be used as an array index? Anybody
    >> know of a good use case for this?
    >>=20
    >> irb(main):020:0> [1, 2, 3][0.3]
    >> 1
    >> irb(main):021:0> [1, 2, 3][0.9]
    >> 1
    >>=20
    >> Just curious,
    >> Jeff
    >>=20
    >> =20

    >=20
    Michael Edgar, Mar 29, 2011
    #4
  5. Jeff Dik

    Guest

    It may do integer truncation, but we need to think of what an Array
    actually is as far as the structure goes. What would one expect to get out
    of [0,1,2][0.3] ? Should it be 30% of the first element? That doesn't seem
    right. With arrays, you are either in one element or not. Integers make
    more sense because they represent the location you're in. Either the 0
    spot, 1 spot, or 2 spot. Think of a row of lockers at school. You can't be
    partially between each locker. It makes more sense to only use one locker
    or the next.

    On Wed, 30 Mar 2011 05:08:36 +0900, Chad Perrin <> wrote:
    > On Wed, Mar 30, 2011 at 03:35:21AM +0900, Jeff Dik wrote:
    >> Why can a floating point number be used as an array index? Anybody
    >> know of a good use case for this?
    >>
    >> irb(main):020:0> [1, 2, 3][0.3]
    >> 1
    >> irb(main):021:0> [1, 2, 3][0.9]
    >> 1

    >
    > I don't know about why, exactly, or about use cases (though I suppose it
    > might just make things easier sometimes, without errors cropping up all
    > over the place if you're working with floating point numbers a lot and
    > are too lazy to do integer conversions yourself). How seems, from a
    > little experimenting, to be self-evident to me:
    >
    > $ irb
    > irb(main):001:0> [1,2,3][0.7]
    > => 1
    > irb(main):002:0> [1,2,3][1.7]
    > => 2
    > irb(main):003:0> [1,2,3][1.1]
    > => 2
    > irb(main):004:0> [1,2,3][-0.1]
    > => 1
    > irb(main):005:0> [1,2,3][-1.1]
    > => 3
    >
    > It looks like it just does integer truncation.
    , Mar 29, 2011
    #5
  6. Jeff Dik

    Xavier Noria Guest

    On Tue, Mar 29, 2011 at 10:38 PM, <> wrote:

    > It may do integer truncation, but we need to think of what an Array
    > actually is as far as the structure goes. What would one expect to get out
    > of [0,1,2][0.3] ? Should it be 30% of the first element? That doesn't seem
    > right.


    Well, alternatively you could get an error.
    Xavier Noria, Mar 29, 2011
    #6
  7. Jeff Dik

    Josh Cheek Guest

    [Note: parts of this message were removed to make it a legal post.]

    On Tue, Mar 29, 2011 at 3:59 PM, Xavier Noria <> wrote:

    > On Tue, Mar 29, 2011 at 10:38 PM, <> wrote:
    >
    > > It may do integer truncation, but we need to think of what an Array
    > > actually is as far as the structure goes. What would one expect to get

    > out
    > > of [0,1,2][0.3] ? Should it be 30% of the first element? That doesn't

    > seem
    > > right.

    >
    > Well, alternatively you could get an error.
    >
    >

    Seems a lot more reasonable, using floats could introduce errors:


    # almost one
    123.6 - 123 + 0.4 # => 0.9999999999999943

    # but truncates to zero
    (123.6 - 123 + 0.4).truncate # => 0

    # do the same math with integers
    (1236 - 1230 + 4) / 10 # => 1
    Josh Cheek, Mar 29, 2011
    #7
  8. On Tue, Mar 29, 2011 at 10:02 PM, Sniper Abandon
    <> wrote:
    > Jeff Dik wrote in post #989828:
    >> Why can a floating point number be used as an array index? =A0Anybody
    >> know of a good use case for this?
    >>
    >> irb(main):020:0> [1, 2, 3][0.3]
    >> 1
    >> irb(main):021:0> [1, 2, 3][0.9]
    >> 1


    > arr =3D [1,2,3,4....]
    > arr[(anyhting).to_i]


    No, it's using #to_int

    irb(main):001:0> idx =3D Object.new
    =3D> #<Object:0x1091fd74>
    irb(main):002:0> %w{foo bar}[idx]
    TypeError: can't convert Object into Integer
    from (irb):2:in `[]'
    from (irb):2
    from /opt/bin/irb19:12:in `<main>'
    irb(main):003:0> class <<idx
    irb(main):004:1> def to_i;p "to_i";1;end
    irb(main):005:1> end
    =3D> nil
    irb(main):006:0> %w{foo bar}[idx]
    TypeError: can't convert Object into Integer
    from (irb):6:in `[]'
    from (irb):6
    from /opt/bin/irb19:12:in `<main>'
    irb(main):007:0> class <<idx
    irb(main):008:1> def to_int;p "to_int";1;end
    irb(main):009:1> end
    =3D> nil
    irb(main):010:0> %w{foo bar}[idx]
    "to_int"
    =3D> "bar"

    #to_i is just a convenience conversion (e.g. String#to_i) while
    #to_int is only used for things which *are* actually an integer. You
    can see all implementators with "ri '#to_int'".

    Kind regards

    robert

    --=20
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
    Robert Klemme, Mar 30, 2011
    #8
  9. On Tue, Mar 29, 2011 at 10:38 PM, <> wrote:
    > It may do integer truncation, but we need to think of what an Array
    > actually is as far as the structure goes. What would one expect to get out
    > of [0,1,2][0.3] ? Should it be 30% of the first element? That doesn't seem
    > right. With arrays, you are either in one element or not. Integers make
    > more sense because they represent the location you're in. Either the 0
    > spot, 1 spot, or 2 spot. Think of a row of lockers at school. You can't be
    > partially between each locker. It makes more sense to only use one locker
    > or the next.


    Yes, of course. That's why Array#[] uses #to_int to determine whether
    the index is integerish. The question to ask would be whether Float
    should be "integerish" - Matz decided "yes" a long time ago and from
    what I can recall there were not much complaints over time. From a
    formal (or mathematical) point of view it's rather the other way
    round: an integer /is a/ float but a float /is not an/ integer. But
    Ruby is a pragmatic language and so I believe they figured that it
    would be more convenient to have Float#to_int than not. YMMV though
    and you can easily overwrite Float#to_int to throw.

    Kind regards

    robert

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
    Robert Klemme, Mar 30, 2011
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mr. SweatyFinger
    Replies:
    2
    Views:
    1,806
    Smokey Grindel
    Dec 2, 2006
  2. Siwat Saibua
    Replies:
    1
    Views:
    837
    Siwat Saibua
    Sep 21, 2007
  3. ssubbarayan
    Replies:
    8
    Views:
    813
    Keith Thompson
    Aug 23, 2008
  4. Saraswati lakki
    Replies:
    0
    Views:
    1,321
    Saraswati lakki
    Jan 6, 2012
  5. teeshift
    Replies:
    2
    Views:
    249
    Chris Pearl
    Dec 1, 2006
Loading...

Share This Page