Unfortunately, it is not always possible to construct a range such that the exact value of the endpoints is retained. Matlab cheats here, and changes the step size to ensure that the endpoints are retained. A Julian range, however, must always have one unique step. For more information, see the PR where linrange was introduced: https://github.com/JuliaLang/julia/pull/6627. I agree that it might make sense to futz with the implementation a bit to ensure that the endpoint is always <= the requested one (see my comment).
In Julia: julia> linrange(.3,.9,3) 0.3:0.30000000000000004:0.9000000000000001 julia> .3 + .3*2 0.8999999999999999 julia> .3 + nextfloat(.3)*2 0.9000000000000001 As compared to Matlab: >> format longE >> s = linspace(.3,.9,3) s = 3.000000000000000e-01 6.000000000000001e-01 9.000000000000000e-01 >> diff(s) ans = 3.000000000000001e-01 2.999999999999999e-01 On Wednesday, July 2, 2014 9:11:18 AM UTC-4, Peter Simon wrote: > > Thanks. I had mistakenly thought that linrange would retain the exact > value of its end points, as does linspace. > > My actual application is to reproduce the functionality of Matlab's > optional histc output: > > [n,bin] = histc(x, edges) > > > Here, (using Matlab notation), bin is an integer-valued vector of the same > length as x such that bin(i) indicates which "bin" of edges is occupied by > x(i). My Julian attempt at reproducing this function used a range named > edges: > > edges = linrange(minimum(x), maximum(x), 20) > bin = [find(edges[1:end-1] .<= t .<= edges[2:end])[1] for t in x] > > > > and it failed due to the issue demonstrated in my first post. I think > that I could use linspace instead of linrange, but for other reasons a > range is preferable in this application. Do we already have this binning > functionality in some other built-in function? I checked Julia's hist(), > but it provides only the first output of Matlab's bin. > > Thanks, > --Peter > > On Tuesday, July 1, 2014 11:59:44 PM UTC-7, Ivar Nesje wrote: >> >> It is not a shocker to me. The problem is that Floating point numbers >> represent binary fractions, and there is no way for linrange() to actually >> get equidistant values you are looking for. It has to do approximations, >> and thus it will sometimes miss closest possible value. That means equality >> checks on floating point numbers should be used with extreme care. >> >> Our implementation reuses the old step size when indexing a FloatRange >> with a range, but we could probably do better if we tried to keep the last >> point equal. >> >> I reopened https://github.com/JuliaLang/julia/issues/7420 to keep track >> of this issue. >> >> Ivar >> >> kl. 07:07:25 UTC+2 onsdag 2. juli 2014 skrev Peter Simon følgende: >>> >>> The final result below seems really strange to me. A bug? >>> >>> julia> x = linrange(1,10,20) >>> 1.0:0.47368421052631576:10.0 >>> >>> >>> julia> 10 .<= x # Gives expected result >>> 20-element BitArray{1}: >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> true >>> >>> julia> 10 .<= x[end] # Gives expected result >>> true >>> >>> julia> 10 .<= x[2:end] # The last entry in this result is a shocker to >>> me! >>> 19-element BitArray{1}: >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> false >>> >>> >>> >>> Here is the version info: >>> >>> >>> julia> versioninfo() >>> Julia Version 0.3.0-prerelease+3987 >>> Commit 7dd97fa (2014-06-30 23:12 UTC) >>> Platform Info: >>> System: Windows (x86_64-w64-mingw32) >>> CPU: Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz >>> WORD_SIZE: 64 >>> BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY) >>> LAPACK: libopenblas >>> LIBM: libopenlibm >>> >>>