Floats as array index

436 views
Skip to first unread message

Øyvind Grotmol

unread,
Mar 9, 2012, 8:07:33 AM3/9/12
to julia-dev
julia> a=[1,2,3]
[1, 2, 3]

julia> a[3/2]
2

I find this confusing, especially since in many other languages the
result would have been a[1]. Personally I would have preferred if
floats were not automatically converted to integers when used as array
indices, but rather an exception thrown.

Regards,
Øyvind

Stefan Karpinski

unread,
Mar 9, 2012, 8:23:10 AM3/9/12
to juli...@googlegroups.com
Yeah, there's been some debate about this. I take responsibility for the current behavior. The main motivation for it is that [1,2,3][end/2] == 2. In terms of what converting a float to an integer does in general, I think that truncation is only more expected because of unfortunate historical artifact. Julia rounds floats when converting to integers, which is almost always better and avoids a lot of numerical pitfalls for newbie programmers (e.g. when you expect an integral value but float precision gives you something that's close but not quite; truncation can easily give you an answer that's off by one). Whether conversion should be done automatically is a completely different issue.

Øyvind Grotmol

unread,
Mar 9, 2012, 9:41:26 AM3/9/12
to julia-dev
I agree about int(3/2)==2, that makes sense. My two cents are just
that I would rather have [1,2,3][pi] give an exception, and have to
write [1,2,3][int(end/2)] when the rounding behaviour is desired. I am
afraid that the automatic conversion is a bit too magic and can
frequently hide bugs that are hard to find, where the programmer was
expecting an integer result but got a floating point which is then
rounded.

Stefan Karpinski

unread,
Mar 9, 2012, 9:49:15 AM3/9/12
to juli...@googlegroups.com
There's a pretty solid argument to be made for that. I suspect Jeff agrees with you as well.

Viral Shah

unread,
Mar 9, 2012, 9:50:23 AM3/9/12
to juli...@googlegroups.com
I personally would prefer this to be an error too, and do an explicit conversion myself using rounding that may be appropriate for the case at hand. An exception would be allowing cases where integers happen to be represented as floating point numbers - a[2.0] for example.

-viral

Jasper

unread,
Mar 9, 2012, 1:04:15 PM3/9/12
to juli...@googlegroups.com
One point of view is of that of someone using an array as a way to
decreasing searching for collisions in a simulation, or to have a
'world map' and accessing by entering positions as floats(possibly with
some factor) to get on which square of the map you are. He will
probably want it always rounded up, then (1-dimensionally)
`world_lists[n]` will contain all the objects from `n-1` to `n`, and
not have a shift of an half in there.

If arrays were 0-starting he'd want it to round down, indeed in C
`(int)some_float` floors it.

It can easily be extended to multiple dimensions by using an array of
arrays. But now i notice `[[1,2,3],[1,2,3]]` appends it. Hmm `[[1 2 3],
[4 5 4]]` is for multidimensional arrays. `[[{1} {2} {3}], [{4} {5}
{4}]]` does the same, i guess you're already aware vectors and matrices
act a little weird. Presumably `{}` works fine.

That said, someone implementing that will probably have a
`get_world_square(world, x,y)` anyway.

Patrick O'Leary

unread,
Mar 9, 2012, 2:56:58 PM3/9/12
to juli...@googlegroups.com
As a point of reference, MATLAB forbids this unless you are within eps() of an integer:

>> x = 1:10;
>> x(2.5)
Subscript indices must either be real positive integers or logicals.
 
>> x(2+eps(2))
Subscript indices must either be real positive integers or logicals.
 
>> x(2+eps(2)/2)
ans =
     2

Viral Shah

unread,
Mar 9, 2012, 3:34:50 PM3/9/12
to juli...@googlegroups.com
This is because 2+eps(2)/2 is the same as 2. There are no floating point numbers between 2 and 2+eps(2).

-viral

Patrick O'Leary

unread,
Mar 9, 2012, 3:41:27 PM3/9/12
to juli...@googlegroups.com
Right, my point being that 2+eps(2)/2 is definitely a floating-point type, and that the indexing behavior (where 2.5 is not acceptable) is due to checking the value, not the type. Naturally this is not a suggestion that Julia follow this path.


On Friday, March 9, 2012 9:34:50 AM UTC-6, Viral Shah wrote:
This is because 2+eps(2)/2 is the same as 2. There are no floating point numbers between 2 and 2+eps(2).

-viral

Stefan Karpinski

unread,
Mar 9, 2012, 4:40:41 PM3/9/12
to juli...@googlegroups.com
Yeah, I'm not at all comfortable with floating point indexing working depending on the value rather than the type. Of course, integer indexing works depending on the value (in or out of bounds), but this doesn't really all feel the same.

kem

unread,
Mar 9, 2012, 8:36:09 PM3/9/12
to juli...@googlegroups.com
Just to add another opinion:

I'm sympathetic to the MATLAB approach, but am sort of convinced by Oyvind's example. It seems to me that if someone really wanted to use an equation to index an array, they'd be ok with an explicit conversion.

jolson

unread,
Apr 21, 2012, 9:59:28 PM4/21/12
to juli...@googlegroups.com
I'm certainly not the expert among us. Nevertheless, I would like to offer a different view on why rounding down might be natural when using a float as an array index.

Assume we are in a language with zero-based indexing and think of a one-dimensional array as being a ruler with a natural-number graduation ("0", "1", "2", ...) that marks the distance from the edge of the ruler (with "0" being right at the edge). An array cell is the space between two consecutive graduations, with cell n lying between graduations n and n + 1. Using a real number (in practice, a float) to specify a point on the ruler, we land in some cell. A natural way to convert from a real to a natural number (rather, from float to an int (perhaps even an uint?)) is therefore to round down, because that way, the cell pointed to is an invariant.

The ruler analogy is less clear when it comes to one-based indexing. I suppose you could say rounding up would be the corresponding conversion convention.

Pondering the issue more, one might even question using floats at all for pointing to an array cell. The precision needed for hitting cell n is the same for large n as it is for small, therefore, a fixed-precision type might be more appropriate. An analogous issue was discussed regarding Ardour (a very nice, free digital audio workstation). In Ardour, points on the time axis are currently represented by a floating point number, even though time coordinates towards the end of the song really have the same need for precision as do times near the beginning. It works in practice, but it's perhaps not the nicest way to do it.
Reply all
Reply to author
Forward
0 new messages