2015-10-21 18 views
8

Tôi cố gắng để hiểu mã này:(x: y) nhà điều hành trong Julia

r = (1:10) - (4/1) 
    println(r) 

Output:

-3.0: 1,0: 6,0

tôi đã hiểu tại sao tôi có -36. Nhưng tại sao tôi nhận được giá trị đó ở giữa (1.0)? Làm thế nào để Julia tính toán nó? Hoặc làm thế nào tôi có thể google nó?

Trả lời

12

(first:step:last) cú pháp đại diện cho một loại Range trong Julia

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

Nếu một phần bước được bỏ qua, theo mặc định nó được giả định 1

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

Một Range là một cái nhìn nhỏ gọn của một loạt

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

Vì vậy, nó mong đợi ed rằng một loại RangeVector làm theo các quy tắc tương tự ví dụ khi bạn thêm một giá trị không đổi như thế này:

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

hoặc thậm chí thêm hai vectơ cho bạn hiệu quả tương tự thêm đại diện phạm vi của họ như thế này:

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

tốt giải thích, cảm ơn! –

+1

Nó có lẽ chỉ là một lỗi đánh máy, nhưng không đúng là '1:10 === 1: 1: 10', chỉ là' 1:10 == 1: 1: 10'. Đầu tiên là 'UnitRange' và thứ hai là' StepRange'. Cũng có thể nói rằng 'isa (1: 10, AbstractVector) # => true'. –

+0

Cảm ơn @Andreas vì bình luận của anh ấy về '1:10! == 1: 1: 10' thực sự nó là một lỗi đánh máy, tôi chỉnh sửa nó. bây giờ '1:10 == 1: 1: 10 # => true' –

3

Nhà điều hành phân chia trong 4/1 trả lại Float64. Mặc dù Phạm vi ban đầu là kích thước 1 Int Phạm vi bước, sau khi thêm dấu phẩy động vào cả hai bên, nó sẽ trở thành Phạm vi Float64. Như vậy, kích thước bước 1.0 được tạo ra bằng cách chuyển đổi kích thước bước nguyên số ẩn (các số dấu phẩy động được phân bố không đồng nhất, do đó bước đồng nhất là một chút khó khăn - đôi khi có các vấn đề làm tròn).

2

Bạn có thể thấy điều này khi áp dụng float để một khoảng thời gian:

julia> 1:10 
1:10 

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

và khuyến mãi này là cần thiết trước khi thêm vào Float64 4/1 (4.0).

Tương tự như vậy, khi thêm một số nguyên cho một julia phao "khuyến khích" các số nguyên cho một phao trước khi thêm/trừ:

julia> 1 + 2.0 
3.0 

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

thấy the promotion rules:

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

Bạn có thể @which theo chức năng gọi tất cả các con đường xuống để hiểu những gì đang xảy ra (tất cả các cách để the following):

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)) 

và do đó khuyến khích bổ sung Int64 và Float64.


Lưu ý trong chủ hiển thị các khoảng thời gian là hơi ít gây nhầm lẫn/nhập nhằng:

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