2015-10-21 25 views
8

sto cercando di capire questo codice:(x: y) operatore Julia

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

uscita:

-3.0: 1,0: 6,0

ho capito perché ho ottenuto -3 e 6. Ma perché ho ottenuto quel valore nel mezzo (1.0)? Come lo calcola Julia? O come posso google?

risposta

12

(first:step:last) sintassi rappresentano un tipo Range in Julia

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

Se parte passaggio viene omesso, per default si presuppone 1

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

Un Range è una vista compatta di una serie

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

Quindi è previsto Ed che un tipo Range e Vector seguono le stesse regole ad esempio quando si aggiunge un valore costante come questa:

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

o anche l'aggiunta di due vettori ti danno lo stesso risultato di aggiungere la loro rappresentazione gamma come questo:

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

buona spiegazione, grazie! –

+1

Probabilmente è solo un refuso, ma non è vero che '1:10 === 1: 1: 10', solo che' 1:10 == 1: 1: 10'. Il primo è un 'UnitRange' e il secondo è un' StepRange'. Potrebbe anche essere utile ricordare che 'isa (1: 10, AbstractVector) # => true'. –

+0

Grazie a @Andreas per il suo commento su '1:10! == 1: 1: 10', in realtà era un refuso, lo modifico. ora '1:10 == 1: 1: 10 # => true' –

3

L'operatore di divisione in 4/1 restituisce un Float64. Sebbene l'intervallo originale sia un intervallo di dimensioni 1 Int, dopo aver aggiunto un punto mobile su entrambi i lati diventa un intervallo Float64. Come tale, una dimensione di passo di 1.0 viene creata convertendo la dimensione del passo dell'intero implicito (i numeri in virgola mobile sono distribuiti in modo non uniforme, quindi lo stepping uniforme è un po 'complicato - a volte ci sono problemi di arrotondamento).

2

Si può vedere questo quando si applica float ad un intervallo:

julia> 1:10 
1:10 

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

e questa promozione è necessario prima di aggiungere al float64 4/1 (4.0).

Analogamente, quando si aggiunge un numero intero in una julia float "promuove" il numero intero per un galleggiante prima di aggiungere/sottrarre:

julia> 1 + 2.0 
3.0 

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

vedi the promotion rules:

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

È possibile @which seguire la funzione chiama fino in fondo per capire cosa sta succedendo (fino a 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)) 

e quindi l'aggiunta di promozione di Int64 e Float64.


Nota in master la visualizzazione di intervallo è un po 'meno confusione/ambiguo:

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 
Problemi correlati