Julia中的 (x:y) 运算符

8
我正在尝试理解这段代码:
  r = (1:10) - (4/1)
    println(r)

输出:

-3.0:1.0:6.0

我知道为什么会得到-36,但中间的值(1.0)是如何计算的呢?Julia是如何计算的?或者我该如何在谷歌上查找相关信息呢?

3个回答

12

(first:step:last) 语法在 Julia 中表示一个 Range 类型。

typeof(1:10) # => UnitRange{Int32}

如果省略步骤部分,默认情况下认为它是1

1:10 == 1:1:10 # => true

Range是一系列数据的精简视图。

collect(1:10) # => 10-element Array{Int32,1}:
#  1
#  2
#  3
#  4
#  5
#  6
#  7
#  8
#  9
# 10

因此,预计一个Range类型和一个Vector遵循相同的规则,例如当您添加一个常量值时,如下所示:
collect(1+(1:10))==collect(1:10)+1 # => true

甚至将两个向量相加,也会得到与它们的范围表示相加相同的结果,就像这样:

collect((1:10)+(1:10))==collect(1:10)+collect(1:10) # => true

1
这可能只是一个笔误,但 1:10 === 1:1:10 不正确,只有 1:10 == 1:1:10 才对。前者是 UnitRange,后者是 StepRange。另外,值得一提的是 isa(1:10,AbstractVector) # => true - Andreas Noack
感谢@Andreas对1:10 !== 1:1:10的评论,实际上那是个笔误,我已经修改了。现在1:10 == 1:1:10 # => true - Reza Afzalan

3

4/1 中的除法运算符返回一个 Float64 类型。尽管原始范围是一个大小为1的 Int 步长范围,但在两边添加浮点数后,它变成了一个 Float64 范围。因此,通过将隐式整数步长转换为浮点数步长创建了一个步长为1.0的范围(浮点数是非均匀分布的,因此均匀步进有点棘手 - 有时会存在舍入问题)。


2
当应用 float 到一个区间时,你会看到这个结果:
julia> 1:10
1:10

julia> float(1:10)
1.0:1.0:10.0

在将4/1 (4.0)添加到Float64之前,需要进行此推广。

同样,在将整数添加到浮点数julia时,“提升”整数以便在添加/减去之前与浮点数相加:

julia> 1 + 2.0
3.0

julia> @which 1 + 2.0
+(x::Number, y::Number) at promotion.jl:172

请查看升级规则

+(x::Number, y::Number) = +(promote(x,y)...)

您可以一直跟踪函数调用,直到了解发生了什么(一直跟踪到以下位置):

julia> @which +(1:10, 2.0)
+(A::AbstractArray{T,N}, x::Number) at arraymath.jl

julia> @which .+(1:10, 2.0)
.+(r::Range{T}, x::Real) at range.jl

julia> @which .+(2.0, 1:10)
.+(x::Real, r::UnitRange{T<:Real}) at range.jl

# which is defined as
.+(x::Real, r::UnitRange)  = range(x + r.start, length(r))

因此,需要进行Int64和Float64的推广添加。


请注意,在主版本中,间隔的显示略微不那么混乱/含糊。

julia> float(1:10)
10-element FloatRange{Float64}:
 1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0

julia> 1:10
10-element UnitRange{Int64}:
 1,2,3,4,5,6,7,8,9,10

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接