Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

float ranges: mismatch between length and bounds error #329

Closed
StefanKarpinski opened this issue Jan 5, 2012 · 9 comments
Closed

float ranges: mismatch between length and bounds error #329

StefanKarpinski opened this issue Jan 5, 2012 · 9 comments
Assignees
Labels
bug Indicates an unexpected problem or unintended behavior

Comments

@StefanKarpinski
Copy link
Member

julia> r = 2.0^53-2:2.0^53+3
9.00719925474099000e+15:9.00719925474099600e+15

julia> r[1]
9.00719925474099000e+15

julia> r[2]
9.00719925474099100e+15

julia> r[3]
9.00719925474099200e+15

julia> r[4]
9.00719925474099200e+15

julia> r[5]
9.00719925474099400e+15

julia> r[6]
9.00719925474099600e+15

julia> r[7]
9.00719925474099600e+15

julia> r[8]
9.00719925474099600e+15

julia> r[9]
BoundsError()
in ref, /Users/stefan/projects/julia/j/range.j:76
in run_repl, /Users/stefan/projects/julia/j/client.j:22
in _start, /Users/stefan/projects/julia/j/client.j:134

julia> length(r)
7
@JeffBezanson
Copy link
Member

There are also corner cases at the other end of the dynamic range:

julia> r = 1.0:1e-19:2.0
1.0:9.99999999999999975e-20:2.0

julia> r[1]
1.0

julia> r[2]
1.0

julia> length(r)
0

@JeffBezanson
Copy link
Member

Maybe the fix is to generalize the step == 0 check to step/start < eps(start) to disallow such ranges.

@StefanKarpinski
Copy link
Member Author

So the solution to this is just to disallow the range 2.0^53-2:2.0^53+3? That seems like an incredible copout to me. It seems to me that the correct answer is to have a range object that produces the following sequence of values:

julia> for x = float(2^53-2:2^53+3)
         println(x)
       end
9.00719925474099000e+15
9.00719925474099100e+15
9.00719925474099200e+15
9.00719925474099200e+15
9.00719925474099400e+15
9.00719925474099600e+15

StefanKarpinski added a commit that referenced this issue Jan 8, 2012
@StefanKarpinski
Copy link
Member Author

I find it highly questionable that range lengths are mapped to Int. This means that on a 32-bit machine, we have length(-2.0^53:2.0^53) == 1. That's very broken.

@JeffBezanson
Copy link
Member

OK, Float64 ranges (or all ranges) can always have Int64 lengths if you want.

I'm worried about the change to done, especially for Range1. It seems like it might be a lot slower. Maybe it's time to cache the lengths of ranges.

Ranges where the step is less than eps(start) are questionable: their lengths can overflow 64-bit counters, and they can have adjacent elements that are equal. But if your fix performs well and you're happy with it I'll go along with it.

@StefanKarpinski
Copy link
Member Author

Computing the length upon construction might make a lot of sense. I agree that ranges with adjacent elements that are equal are weird, but it seems like the best solution. Making the range 2.0^53-2:2.0^53+3 illegal seems kind of bogus. Another argument for storing length explicitly is something like this:

julia> r = -2:3
-2:3

julia> length(r)
6

julia> r += 2.0^53
9.00719925474099000e+15:9.00719925474099600e+15

julia> length(r)
7

If the length of the former was part of its state, then this could work sanely but copying the length of the range. Maybe we should store the start, step and length or a range instead. I think this came up once before and we felt that keeping the stop value around was a good idea to avoid confusion. But maybe we shouldn't bother and just compute the last value for display and make sure that if a range is input as it is printed, you'll get back the same length range.

@JeffBezanson
Copy link
Member

Things are definitely better now. But we still have stuff like

julia> length(0:1e-20:1)
0

Even with 64-bit lengths, you can't handle everything.

I'm not sure it's so bad to use Int32 for length on 32-bit systems. You don't generally expect to have more than 2^32-1 of anything on a 32-bit system.

@StefanKarpinski
Copy link
Member Author

See 44b1aaf and e35cc22.

@JeffBezanson
Copy link
Member

Can we close this now?

@ghost ghost assigned StefanKarpinski Jan 11, 2012
StefanKarpinski pushed a commit that referenced this issue Feb 8, 2018
Support IndexStyle, IndexLinear, IndexCartesian
LilithHafner pushed a commit to LilithHafner/julia that referenced this issue Oct 11, 2021
)

This is due to implementation in SortingAlgorithms.jl.
cmcaine pushed a commit to cmcaine/julia that referenced this issue Nov 11, 2022
I got tricked by my own excitement beginning the julia track.
I started solving the Nucleotide Count exercise without a complete reading of its introduction;
the comment at the beginning seemed just enough:

> count_nucleotides(strand)
> The frequency of each nucleotide within `strand` as a dictionary.
> Invalid strands raise a `DomainError`.

So I read **frequency** and I think: count(nt) / length(strand) 

It was fun solving that.. Untill the tests revealed  my mistake:
we are asked to return the count of each nucleotide: not their frequencies.

To avoid the confusion -for future students- I'd propose to replace "frequency" with "count" in the comment of the exercise's .jl file.
Keno pushed a commit that referenced this issue Oct 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Indicates an unexpected problem or unintended behavior
Projects
None yet
Development

No branches or pull requests

2 participants