# Why does scientific notation break the range function?

**URL:** <https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014>\
**Category:** New to Julia\
**Created:** [April 25, 2022, 8:46pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014 "2022-04-25T20:46:57Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [April 26, 2022, 2:41pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/21 "2022-04-26T14:41:05Z")

</div>

Split this topic on April 26, 2022, 2:41pm UTC

7 posts were split to a new topic: [Frustrated with frustrated beginners](https://discourse.julialang.org/t/frustrated-with-frustrated-beginners/80067)

---

<div class="post-metadata">

**Author:** ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)\
**Post date:** [April 26, 2022, 8:24am UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/24 "2022-04-26T08:24:44Z")

</div>

I’m wrong about the syntax being free, currently `1E6 === 1e6`. So this would be a breaking change for a small gain. Ignore.

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [April 26, 2022, 8:38am UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/25 "2022-04-26T08:38:59Z")

</div>

Good catch. That’ll be fixed by  
[https://github.com/julia-vscode/julia-vscode/pull/2862](https://github.com/julia-vscode/julia-vscode/pull/2862)

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 26, 2022, 12:07pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/26 "2022-04-26T12:07:14Z")

</div>

> [@jules](#):
>
> Floating point “integers” like 1e10 usually don’t match their closest integers perfectly, but there’s rounding error involved.

Actually, they “usually” _do_ match: `Float64` floating-point numbers represent _all_ integers exactly up to `maxintfloat(Float64) = 2^53`, about `10^16`.

Moreover, because `10` contains a factor of `2`, binary floating point represents many integers n \times 10^m = (n \times 5^m) \times 2^m exactly up to much bigger values, up to about `1e22` — even in single precision (`Float32`), which only represents all integers exactly up to `maxintfloat(Float32) = 2^24 ≈ 1.6e7`, you can represent “scientific-notation” numbers `1fN` exactly up to `1e10`. It only goes wrong at `1e23 == 99999999999999991611392` (in `Float64`) or `1f11 == 99999997952` (in `Float32`).

In short, `Float64` literals are exact for essentially any practical array length.

The main concerns in the discussions that [I linked above](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/10) were different. For example, if you accept floating-point lengths in a few functions for convenience, which functions? It would be oddly inconsistent for them to work in only some functions (e.g. ranges, `zeros`, …) but not others, but then you have an ever-expanding set of conversion methods that you need to remember to write.

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [April 26, 2022, 1:12pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/28 "2022-04-26T13:12:41Z")

</div>

I think we should make an exception here, for pragmatic reasons.

My argument is that, despite what you write floats representing “many integers” exactly (well because), but not all, and length an integer (counted, never measured), I realized no float for length would be problematic:

```julia
julia> range(0, 10, length=1000) # returns same as range(0e0, 10e0, length=1000)
0.0:0.01001001001001001:10.0

```

That looked awfully binary-like to me at first. 🙂 I realized despite the integer count, it must be converted to a Float64 because of a division somewhere, so why not allow both operands Float64? You can construct the same range with all 3 numbers floats, or as there mixed with first and last numbers integers:

```julia
julia> 0:0.01001001001001001:10
0.0:0.01001001001001001:10.0

```

With ranges hugely important, even with the above special syntax, allowing mixing types, I think we should make the exception in this case (sort of for consistency with it).

I was thinking we need to check for extreme values for floats and disallow, just was we need for negative “lengths” (so run-time check likely not an objection for performance reasons):

```julia
julia> range(0e0,10e0,length=-1000)
ERROR: ArgumentError: range(0.0, stop=10.0, length=-1000): negative length

```

> [@stevengj](#):
>
> In short, `Float64` literals are exact for essentially any practical array length.

Right, and while technically you’re not constructing an array until you do e.g. `collect(range(0e0,10e0,length=10))` or use the range with an array in other ways.

Jeff wrote on github (regarding shortening stack-traces), so I doubt it will happen in general (while Karpinski has some exception for code that Julia shows but Python wouldn’t since there implemented in C)::

> This has come up a couple times in the past and I generally resist hiding information.

---

<div class="post-metadata">

**Author:** ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)\
**Post date:** [April 26, 2022, 1:21pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/29 "2022-04-26T13:21:54Z")

</div>

Rather than upend the entire language, you can

```julia
myrange(start,stop,len) = range(start,stop,length=Int(len))

```

```julia
julia> myrange(0,10,1e3)
0.0:0.01001001001001001:10.0

```

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [April 26, 2022, 1:35pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/30 "2022-04-26T13:35:33Z")

</div>

I would say it overstating it upends “the entire language”, but that’s not going to be helpful to beginners… 🙂 And I was thinking extreme values need checking (or not?), so this might be buggy code, but a step in the right direction for Base.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [April 26, 2022, 1:54pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/31 "2022-04-26T13:54:28Z")

</div>

Curious discussion here. Poor OP! As a teacher we learn to deal with frustrating learning curves, and with the fact that the questions are almost always the same, it is the people that change 🙂 .

My answer to this would be, simply:

Julia makes a clear difference between integers and floats, so the practical syntax for that is

```julia
range(1,10,length=10^3)

```

because literal powers of integers are integers, we can write

```julia
for i in 1:10^3
end

```

I don’t know if Matlab accepts `1e3` there, for example.

And note that this is another difference from other languages, perhaps Matlab, such that be careful with

```julia
julia> div(10^2,10^3)
0

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [April 26, 2022, 1:56pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/32 "2022-04-26T13:56:03Z")

</div>

> [@Palli](#):
>
> I think we should make an exception here, for pragmatic reasons.

Please don’t. Being consistent with `Int`s and not allowing floats is going to be a lot less confusing in the long run. Making the language optimally welcoming for the first week of use, and annoying for the next 20+ years is not the right tradeoff, imho.

---

<div class="post-metadata">

**Author:** ![chadagreene](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chadagreene/32/34924_2.png) [@chadagreene](https://discourse.julialang.org/u/chadagreene)\
**Post date:** [April 26, 2022, 3:14pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/33 "2022-04-26T15:14:44Z")

</div>

> [@lmiq](#):
>
> Curious discussion here. Poor OP!

It’s actually kind of awesome to read how the different members of the forum think about these problems. Some of it is totally over my head, but an interesting discussion, nonetheless!

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [April 26, 2022, 3:22pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/34 "2022-04-26T15:22:15Z")

</div>

I would rather point out that Matlab accepts those inputs because it does not really know anything else but a double. 😉

Seriously, being able to catch type errors is valuable. The argument is optional, which means it could be `nothing`. (So far with me?) Hence, a union of `Nothing` and `Int`.

---

<div class="post-metadata">

**Author:** ![stephancb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephancb/32/14243_2.png) [@stephancb](https://discourse.julialang.org/u/stephancb)\
**Post date:** [April 26, 2022, 3:29pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/35 "2022-04-26T15:29:33Z")

</div>

I think this is true for older versions of Matlab. Nowadays there are, e. g., [16 bit integer arrays](https://se.mathworks.com/help/matlab/ref/int16.html). Probably a value like `1000` by default still becomes a 1x1 double matrix, but you could force it to be a 1x1 int16 matrix.

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [April 26, 2022, 3:37pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/36 "2022-04-26T15:37:47Z")

</div>

Integer types have existed in Matlab for quite long but _literals_ (e.g. `1000`) are doubles, so it would be unreasonably inconvenient to require integer types to be used as arguments to common functions, not to speak of backwards compatibility issues with changing it.

---

<div class="post-metadata">

**Author:** ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)\
**Post date:** [April 26, 2022, 4:02pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/37 "2022-04-26T16:02:40Z")

</div>

For what it’s worth, `LinRange` gives a better stacktrace (and is a cleaner drop-in replacement for `linspace`):

```julia
julia> LinRange(0, 1, 1e3)
ERROR: MethodError: no method matching LinRange(::Int64, ::Int64, ::Float64)
Closest candidates are:
  LinRange(::Any, ::Any, ::Integer) at range.jl:563
Stacktrace:
 [1] top-level scope
   @ REPL[14]:1

julia> range(0, 1, length=1e3)
ERROR: TypeError: in keyword argument length, expected Union{Nothing, Integer}, got a value of type Float64
Stacktrace:
 [1] top-level scope
   @ REPL[15]:1

```

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [April 26, 2022, 4:18pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/38 "2022-04-26T16:18:55Z")

</div>

> [@chadagreene](#):
>
> It’s actually kind of awesome to read how the different members of the forum think about these problems.

The Julia community is very particular in this sense, as any post here gets answers from newbies, relatively new users, computer engineers working at Julia Computing, language founders, world-class computer scientists, all together. And many of the new questions bring back heated discussions of the past, but even then it is curious that it is common that we can find and link the issue in github where the decision was taken, sometimes, as here, many many years ago.

Nobody knows, at the same time, the background of the poster. So he/she maybe someone with a strong background in computer sciences, or someone that is just starting to script something. I have more than once answered a question and, later, realized that the poster was someone with a much more deep knowledge of the question than me. Probably having to read my answer was irritating. And the same thing goes otherwise, sometimes people get answers here that are way far from what they have as a background. The good thing is that with some persistence the amount we learn about computer and programming is huge.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [April 26, 2022, 4:54pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/39 "2022-04-26T16:54:48Z")

</div>

What about when you do floating point calculations to come up with the indices, isn’t that likely to lead to small rounding errors so that the exact integers aren’t hit exactly? For example when doing divisions with divisors that are not powers of two.

---

<div class="post-metadata">

**Author:** ![chadagreene](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chadagreene/32/34924_2.png) [@chadagreene](https://discourse.julialang.org/u/chadagreene)\
**Post date:** [April 26, 2022, 3:58pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/40 "2022-04-26T15:58:26Z")

</div>

> [@Frustrated with frustrated beginners](https://discourse.julialang.org/t/frustrated-with-frustrated-beginners/80067/20):
>
> But on reflection, wasn’t the error message actually pretty _good_ ?

No, it’s terrible! The “useful” part of the error message, `Union{Nothing, Integer}` is a far too cryptic way to say, “Hey buddy, use a dang Integer instead of a Float!”

And I’m not trying to be a troll here, but I actually _still_ can’t mentally parse what `Union{Nothing, Integer}` is actually saying. All users can do is try to figure it out from the words that are there. I tried entering it into the REPL and it returned `Union{Nothing, Integer}`. I tried searching the help docs for `Nothing` because that part is very confusing, and this is what I got:

```julia
help?> Nothing
search: Nothing nothing isnothing

  Nothing

  A type with no fields that is the type of nothing.

  See also: isnothing, Some, Missing.

```

Sorry to revert back to insults, but it’s a lousy, no-good error message! 🙂

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [April 26, 2022, 4:02pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/41 "2022-04-26T16:02:32Z")

</div>

> [@chadagreene](#):
>
> No, it’s terrible! The “useful” part of the error message, `Union{Nothing, Integer}` is a far too cryptic way to say, “Hey buddy, use a dang Integer instead of a Float!”

FWIW, here is an example of a TypeScript error message for union types

```julia
Argument of type 'boolean' is not assignable to parameter of type 'string | number'.

```

Off the top of my hat the following type constructions could be problematic, too: `Tuple`, `Vararg`, `UnionAll`.

If you want to take a look into the [machinery](https://github.com/JuliaLang/julia/blob/master/test/subtype.jl).

---

<div class="post-metadata">

**Author:** ![jacobusmmsmit](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jacobusmmsmit/32/217669_2.png) [@jacobusmmsmit](https://discourse.julialang.org/u/jacobusmmsmit)\
**Post date:** [April 26, 2022, 4:05pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/42 "2022-04-26T16:05:10Z")

</div>

> [@chadagreene](#):
>
> “Hey buddy, use a dang Integer instead of a Float!”

```julia
TypeError: in keyword argument length, expected Union{Nothing, Integer}, got a value of type Float64

```

- `TypeError`: The error is about the type of something in the function,
- `in keyword argument length`: This is where there is some type error, in the `length` argument,
- `expected Union{Nothing, Integer}, got Float64`: there’s your “Hey buddy”! It told you what was expected and then what it got.

I appreciate that the whole `Union` part may not be so obvious, but by googling\* `Julia Union` you get a pretty good explanation + example of what a `Union` type would mean.

\*Really shouldn’t have to do that, but tbh I’m just lazy so I google everything

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [April 26, 2022, 4:10pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/43 "2022-04-26T16:10:53Z")

</div>

Doesn’t even need google:

```julia
help?> Union
(...)

  Union{Types...}

  A type union is an abstract type which includes all instances of any of its argument types. The empty union Union{} is the bottom type of Julia.

  Examples
  ≡≡≡≡≡≡≡≡≡≡

  julia> IntOrString = Union{Int,AbstractString}
  Union{Int64, AbstractString}

  julia> 1 :: IntOrString
  1

  julia> "Hello!" :: IntOrString
  "Hello!"

  julia> 1.0 :: IntOrString
  ERROR: TypeError: in typeassert, expected Union{Int64, AbstractString}, got a value of type Float64

```

which coincidentally is almost exactly the error message that OP saw.

[Previous page](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014.md?page=1)

[Next page](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014.md?page=3)
