# 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:** 1

<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 25, 2022, 8:46pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/1 "2022-04-25T20:46:57Z")

</div>

This line of code creates a 1000 element array of values, evenly spaced from 0 to 10:

```julia
x = range(0,10,length=1000)

```

The code above works perfectly. This line of code, however, throws an error:

```julia
x = range(0,10,length=1e3)

```

As I understand it, `1000` should be the same thing as `1e3`, and I’ve checked to make sure Julia knows they’re equal:

```julia
julia> 1000==1e3
true

```

Can anyone help me understand why `length=1000` works, while `length=1e3` throws an error? Here’s the error message it produces, which to me is 30 lines of cryptic nonsense:

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

Stacktrace:
  [1] top-level scope
    @ ~/Documents/coursework/Untitled-1.ipynb:1
  [2] eval
    @ ./boot.jl:373 [inlined]
  [3] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
    @ Base ./loading.jl:1196
  [4] #invokelatest#2
    @ ./essentials.jl:716 [inlined]
  [5] invokelatest
    @ ./essentials.jl:714 [inlined]
  [6] (::VSCodeServer.var"#164#165"{VSCodeServer.NotebookRunCellArguments, String})()
    @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.6.17/scripts/packages/VSCodeServer/src/serve_notebook.jl:19
  [7] withpath(f::VSCodeServer.var"#164#165"{VSCodeServer.NotebookRunCellArguments, String}, path::String)
    @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.6.17/scripts/packages/VSCodeServer/src/repl.jl:184
  [8] notebook_runcell_request(conn::VSCodeServer.JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}, params::VSCodeServer.NotebookRunCellArguments)
    @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.6.17/scripts/packages/VSCodeServer/src/serve_notebook.jl:13
  [9] dispatch_msg(x::VSCodeServer.JSONRPC.JSONRPCEndpoint{Base.PipeEndpoint, Base.PipeEndpoint}, dispatcher::VSCodeServer.JSONRPC.MsgDispatcher, msg::Dict{String, Any})
    @ VSCodeServer.JSONRPC ~/.vscode/extensions/julialang.language-julia-1.6.17/scripts/packages/JSONRPC/src/typed.jl:67
 [10] serve_notebook(pipename::String, outputchannel_logger::Base.CoreLogging.SimpleLogger; crashreporting_pipename::String)
    @ VSCodeServer ~/.vscode/extensions/julialang.language-julia-1.6.17/scripts/packages/VSCodeServer/src/serve_notebook.jl:136
 [11] top-level scope
    @ ~/.vscode/extensions/julialang.language-julia-1.6.17/scripts/notebook/notebook.jl:32
 [12] include(mod::Module, _path::String)
    @ Base ./Base.jl:418
 [13] exec_options(opts::Base.JLOptions)
    @ Base ./client.jl:292
 [14] _start()
    @ Base ./client.jl:495

```

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [April 25, 2022, 8:48pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/2 "2022-04-25T20:48:31Z")

</div>

`1e3` is a `Float64`, but `Int` is expected.

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [April 25, 2022, 8:49pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/3 "2022-04-25T20:49:18Z")

</div>

```julia
julia> 1000==1e3
true

julia> 1000===1e3
false

```

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [April 25, 2022, 8:52pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/4 "2022-04-25T20:52:48Z")

</div>

> [@chadagreene](#):
>
> which to me is 30 lines of cryptic nonsense

For the start of errors you can ignore what is after Stacktrace: , the first line says it all:

```julia
expected Union{Nothing, Integer}, got a value of type Float64

```

---

<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 25, 2022, 9:12pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/5 "2022-04-25T21:12:26Z")

</div>

I must confess, `Union{Nothing, Integer}` is complete nonsense to me.

The entire error message, including the first line, is unnecessarily cryptic and overly complicated for such a simple issue. Even the first line of the message requires users to understand multiple Julia commands well enough to effectively compute code in their head.

Even as I now understand what the first line is _trying_ to say, I cannot understand how `Union{Nothing, Integer}` is the same thing as saying `Int`. To figure this out, I find myself searching the docs for `Nothing`, and find this:

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

  Nothing

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

  See also: isnothing, Some, Missing.

```

So tell me, what part of this error message is helpful to users who may innocently use `1e3` to represent the number `1000`?

---

<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 25, 2022, 9:16pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/6 "2022-04-25T21:16:00Z")

</div>

> [@chadagreene](#):
>
> So tell me, what part of this error message is helpful to users who may innocently use `1e3` to represent the number `1000` ?

This part:

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

```

This is very helpful.

Unfortunately, there is also a part mentioning a union with `Nothing`, which is pretty confusing.

---

<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 25, 2022, 9:26pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/7 "2022-04-25T21:26:18Z")

</div>

> [@DNF](#):
>
> Unfortunately, there is also a part mentioning a union with `Nothing` , which is pretty confusing.

Yep, and after that there’s 30 lines of Stacktrace garbage that buries the tiny morsel of the error message that could potentially be helpful.

From my perspective as a beginner, cryptic and unhelpful error messages appear to be pretty pervasive in Julia, and it makes it _really_ hard to get started. I don’t know what I’d do without this forum!

But back to the original issue: **Should the `range` function be updated to allow whole numbers for the length definition, even if they’re Floats?**

---

<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 25, 2022, 9:34pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/8 "2022-04-25T21:34:11Z")

</div>

> [@chadagreene](#):
>
> Yep, and after that there’s 30 lines of Stacktrace garbage that buries the tiny morsel of the error message that could potentially be helpful.

I agree this could be better, but the useful part is at the very top, so it’s difficult to agree that it’s buried.

> [@chadagreene](#):
>
> Should the `range` function be updated to allow whole numbers for the length definition, even if they’re Floats?

I don’t think so. Only whole numbers make sense, so restriction to integers make sense, and helps catch errors earlier and more reliably.

A similar discussion was had (on github) concerning indexing with floats, which used to be allowed, way back. I cannot find it at the moment, but it may contain some relevant points.

---

<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 25, 2022, 10:22pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/9 "2022-04-25T22:22:08Z")

</div>

> [@chadagreene](#):
>
> Yep, and after that there’s 30 lines of Stacktrace garbage that buries the tiny morsel of the error message that could potentially be helpful.

Yes, we’d definitely like to abbreviate stack traces by default in the future. See e.g. [Suggestion: abbreviate stack traces by default · Issue #40138 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/40138)

---

<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 25, 2022, 10:27pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/10 "2022-04-25T22:27:00Z")

</div>

> [@chadagreene](#):
>
> Should the `range` function be updated to allow whole numbers for the length definition, even if they’re Floats?

Allowing floating-point values to specify array lengths was discussed pretty early on in the development of Julia (in 2011!), and was ultimately rejected. See the discussion here [Matrix constructors should be able to take floating point value for size · Issue #136 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/136) and here [Pass integer valued floats to matrix constructors · Issue #1972 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/1972) and here [zeros(1e4) -\> ERROR: no method Array(DataType,Float64) · Issue #4275 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/4275) for example.

---

<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 25, 2022, 10:27pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/11 "2022-04-25T22:27:42Z")

</div>

> [@DNF](#):
>
> I don’t think so. Only whole numbers make sense, so restriction to integers make sense, and helps catch errors earlier and more reliably.

For the sake of the big picture, I disagree. When driving a car, I prefer a manual transmission, but I’m a car enthusiast, and I recognize that most people are just driving to the store, and don’t want the extra work of operating a clutch. By the same token, if Julia is to be widely adopted by people who just want to accomplish a task and are not coding enthusiasts, I think it’s an unnecessary burden to make them write this:

```julia
x = range(0,10,length=Integer(1e3))

```

when they could just as easily write this:

```julia
x = range(0,10,length=1e3)

```

Before you point out that many ordinary drivers (especially outside the USA) prefer a manual transmission, I note that no culture has ever gone _back_ to widespread use of manual transmissions after growing accustomed to automatic transmissions.

I am currently coming from MATLAB, which graciously accepts either input:

```matlab
>> x = linspace(0,10,int16(1e3));
>> x = linspace(0,10,1e3);

```

To me, the fact that Julia breaks with `1e3` but not `1000` feels like a small and unnecessary step backward from MATLAB.

---

<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 25, 2022, 10:39pm UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/12 "2022-04-25T22:39:56Z")

</div>

> [@chadagreene](#):
>
> I think it’s an unnecessary burden to make them write this:
> 
> ```julia
> x = range(0,10,length=Integer(1e3))
> 
> ```

You would normally write one of these

```julia
x = range(0,10,length=1000)
x = range(0,10,length=10^3)

```

> [@chadagreene](#):
>
> MATLAB, which graciously

I don’t often see “Matlab” and “graciously” in the same sentence 😁 I’d point out that _all_ number literals are floats in Matlab, though, so you almost have to allow that.

Julia cares about types. I’m afraid it’s just something to get used to.

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [April 26, 2022, 12:44am UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/13 "2022-04-26T00:44:36Z")

</div>

Note that stacktraces are not always that long. Your stacktrace is worse than usual because you are running a Jupyter notebook in VS Code. If you run that one line of code directly in the REPL, you get this:

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

```

Here’s another option if you want to write a long integer:

```julia
range(0, 10, length=1_000_000)

```

In other words, use underscores to make the integer more readable.

---

<div class="post-metadata">

**Author:** ![Ininterrompue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ininterrompue/32/5594_2.png) [@Ininterrompue](https://discourse.julialang.org/u/Ininterrompue)\
**Post date:** [April 26, 2022, 2:28am UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/14 "2022-04-26T02:28:45Z")

</div>

It’s written as `Union{Nothing, Integer}` because the length keyword has been implemented so that it takes in an `Integer`. This is an abstract type which takes into account all kinds of integers, not just 64-bit ones (`Int64`, or `Int`), for example:

> `julia> range(0, 10, length=10^BigInt(100))`  
> `0.0:1.0e-99:10.0`

The range function also has the case where the length is not given, and it’ll default to a stepsize of 1. That’s where the `Nothing` type comes in.

I agree the error message is confusing, as well as `Integer` vs. `Int`, but I don’t think the Union itself is too bad.

---

<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, 4:56am UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/15 "2022-04-26T04:56:04Z")

</div>

How’s this for a toy idea?

```julia
julia> 1E6 === 1_000_000
true

julia> 1E-6
ERROR: Domain error
Integer valued powers of 10 cannot be less than 1. Do you mean 1e-6?

```

Not sure I think this is necessary, and it might just add to the confusion, but the syntax _is_ up for grabs.

---

<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, 5:25am UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/16 "2022-04-26T05:25:47Z")

</div>

I think you’re arguing here for a “do what I mean” behavior. Floating point “integers” like 1e10 usually don’t match their closest integers perfectly, but there’s rounding error involved. So saying something like “9.9999999” is 10 just because it’s very close to 10 invites a lot of bugs and weird behavior. For example, how close should a floating point “integer” be to its next integer so that it is allowed to be used as one? I personally like the decision to just squash that whole class of bugs by requiring integers. If you want the language to “do what I mean” in one simple situation like 1e10 you often have to deal with bad egde cases in other circumstances that are not immediately obvious.

---

<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, 5:31am UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/17 "2022-04-26T05:31:02Z")

</div>

> [@chadagreene](#):
>
> To me, the fact that Julia breaks with `1e3` but not `1000` feels like a small and unnecessary step backward from MATLAB.

In general, Julia is actually very accommodating when it comes to accepting varying input types. Much more so than Matlab. When calling built-in Matlab functions, you will often see that only `double` is accepted (perhaps one or two more built-in types), because it calls into compiled C++ libraries.

Julia functions are very often highly generic, and accept any type that “quacks like a duck”.

What happens if you try

```julia
linspace(int64(0), int64(1), 10)

```

in Matlab? This works in Julia, with all sorts of integers, (after fixing the names).

In Matlab things are built around `double`, and almost everything is a `double`. Stray from that and you soon get in trouble.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [April 26, 2022, 5:36am UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/18 "2022-04-26T05:36:09Z")

</div>

The error thrown by Julia is actually pretty good in this case, and almost the same as Python gives:

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

```

vs

```python
In [1]: import numpy
In [2]: numpy.linspace(0, 1, 1e2)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-2-5b8b1326f642> in <module>
----> 1 numpy.linspace(0, 1, 1e2)
< __array_function__ internals> in linspace(*args, **kwargs)
/usr/local/lib/python3.9/site-packages/numpy/core/function_base.py in linspace(start, stop, num, endpoint, retstep, dtype, a
xis)
    111 
    112 """
--> 113 num = operator.index(num)
    114 if num < 0:
    115 raise ValueError("Number of samples, %s, must be non-negative." % num)
TypeError: 'float' object cannot be interpreted as an integer

```

Allowing floating point values would open a whole another can of worms. For example, `1e10 == 10^10`, but `1e20 != 10^20`.

---

<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, 5:48am UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/19 "2022-04-26T05:48:22Z")

</div>

> [@aplavin](#):
>
> but `1e20 != 10^20` .

Unfortunate example since the left hand side can be represented exactly but the right hand side overflows.

```julia-auto
julia> 1e20 == BigInt(10)^20
true

julia> 10^20
7766279631452241920

```

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [April 26, 2022, 6:37am UTC](https://discourse.julialang.org/t/why-does-scientific-notation-break-the-range-function/80014/20 "2022-04-26T06:37:08Z")

</div>

Indeed, you are right! A better example would probably be `Int(1e16 + 1) == Int(1e16)` which would make `range(... length=1e16 + 1)` very confusing.

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