科學運算及數值運算需要高效能的運算,這樣的情境同樣也適用資料科學及大數據的運算環境。
println("Hello World!")
Hello World!
print("Hello World!") # 不會自動換行
Hello World!
# 這個叫作單行註解
註解是一種執行後,會被編譯器忽略的部份
#=
當然你可以寫多行註解
=#
5
5
2 + 5
7
2.0 + 5
7.0
對於數字的運算來說,他就是一台純粹的計算機
數字對於 Julia 來說並不是"同樣"的
Type | Signed? | Bit size | Smallest value | Largest value |
---|---|---|---|---|
Int8 | T | 8 | $-2^{7}$ | $2^{7} - 1$ |
Uint8 | F | 8 | 0 | $2^{8} - 1$ |
Int16 | T | 16 | $-2^{15}$ | $2^{15} - 1$ |
Uint16 | F | 16 | 0 | $2^{16} - 1$ |
Int32 | T | 32 | $-2^{31}$ | $2^{31} - 1$ |
Uint32 | F | 32 | 0 | $2^{32} - 1$ |
Int64 | T | 64 | $-2^{63}$ | $2^{63} - 1$ |
Uint64 | F | 64 | 0 | $2^{64} - 1$ |
Int128 | T | 128 | $-2^{127}$ | $2^{127} - 1$ |
Uint128 | F | 128 | 0 | $2^{128} - 1$ |
Bool | 8 | false | true |
以上表摘錄自官方網站
typeof(100)
Int64
Int
Int64
Int8(10)
10
電腦儲存數字的方式是用01
的方式儲存及運算
所以一個Int8
(8 bit integer)會以
☐☐☐☐☐☐☐☐
的方式儲存
00000001 就是 1
000000010 就是 2
00000100 就是 4
10000100 則是 -4
typemax(Int8)
127
他相當於 01111111
typemin(Int8)
-128
他則是 10000000
那如果對最大的數+1
的話會怎麼樣?
typemax(Int64) + 1
-9223372036854775808
有趣的事情就發生了!
當 x
跟 y
是整數或是布林值...
~x
: bitwise not,對每個位元做 $\neg x$ 運算,11100
->00011
x & y
: bitwise and,對每個位元做 $x \land y$ 運算x | y
: bitwise or,對每個位元做 $x \lor y$ 運算x $ y
: bitwise xor,對每個位元做 $x \oplus y$ 運算x >>> y
: 位元上,將 x
的位元右移 y
個位數x >> y
: 算術上,將 x
的位元右移 y
個位數x << y
: 將 x
的位元左移 y
個位數Int8(1) << 2 # 將Int8(1)的位元左移2個位數
4
Int8(4) >> 2 # 將Int8(4)的位元右移2個位數
1
~Int8(4) # 00000100 -> 11111011
-5
Int8(4) & Int8(8) # 00000100 & 00001000 = 00000000
0
Int8(4) | Int8(8) # 00000100 | 00001000 = 00001100
12
0.5
0.5
.5
0.5
typeof(0.5)
Float64
2.5e-4
0.00025
Type | Bit size |
---|---|
Float16 | 16 |
Float32 | 32 |
Float64 | 64 |
Float16 | Float32 | Float64 |
---|---|---|
Inf16 | Inf32 | Inf |
-Inf16 | -Inf32 | -Inf |
NaN16 | NaN32 | NaN |
1 / Inf
0.0
1 / 0
Inf
-5 / 0
-Inf
0 / 0
NaN
當 x
跟 y
都是數字...
+x
: 就是 x
本身-x
: 變號x + y
, x - y
, x * y
, x / y
: 一般四則運算div(x, y)
: 商x % y
: 餘數,也可以用rem(x, y)
x \ y
: 跟/
的作用一樣x ^ y
: 次方div(123, 50)
2
123 % 50
23
用在 x
跟 y
都是數值的狀況
x == y
:等於x != y
, x ≠ y
:不等於x < y
:小於x > y
:大於x <= y
, x ≤ y
:小於或等於x >= y
, x ≥ y
:大於或等於+0
會等於 -0
,但不大於 -0
Inf
跟自身相等,會大於其他數字除了 NaN
-Inf
跟自身相等,會小於其他數字除了 NaN
Inf == Inf
true
Inf > NaN
false
Inf == NaN
false
Inf < NaN
false
x = 5.0
5.0
x
5.0
變數開頭可以是字母(A-Z or a-z)、底線或是Unicode(要大於 00A0)
運算符號也可以是合法的變數名稱,例如 +
,通常用於指定function(函式)
δ = 0.00001
1.0e-5
안녕하세요 = "Hello"
"Hello"
打 \delta 之後,按下tab
δ
1.0e-5
\alpha
-tab-\_2
-tab
α₂
UndefVarError: α₂ not defined Stacktrace: [1] top-level scope at In[38]:1
pi
π = 3.1415926535897...
π
π = 3.1415926535897...
ℯ
ℯ = 2.7182818284590...
lower_case
,不過不鼓勵使用底線,除非影響到可讀性CamelCase
的寫法!
,像 transform!()
x = 3
3
2x^2 - 3x + 1
10
(x-1)x
6
1 + 2im
1 + 2im
(1 + 2im) + (3 - 4im)
4 - 2im
(1 + 2im) * (3 - 4im)
11 + 2im
(-4 + 3im)^(2 + 1im)
1.950089719008687 + 0.6515147849624384im
3 / 5im == 3 / (5*im)
true
real(1 + 2im)
1
imag(3 + 4im)
4
conj(1 + 2im)
1 - 2im
abs(3 + 4im) # 複數平面上的向量長度
5.0
angle(3 + 4im) # 複數平面上的向量夾角
0.9272952180016122
1 + Inf*im
1.0 + Inf*im
1 + NaN*im
1.0 + NaN*im
(1 + NaN*im)*(3 + 4im)
NaN + NaN*im
2//3
2//3
-6//12 # 會自動約分
-1//2
5//-20 # 自動調整負號
-1//4
numerator(2//10) # 約分後的分子(numerator)
1
denominator(7//14) # 約分後的分母(denominator)
2
10//15 == 8//12
true
2//4 + 1//7
9//14
3//10 * 6//9
1//5
float(3//4) # 轉成浮點數
0.75
1//(1 + 2im) # 分母實數化
1//5 - 2//5*im
5//0 # 可以接受分母為0
1//0
3//10 + 1 # 與整數運算
13//10
3//10 - 0.8 # 與浮點數運算
-0.5
2//10 * (3 + 4im) # 與複數運算
3//5 + 4//5*im
true
true
typeof(false)
Bool
!x
:true
變成false
,false
變成true
!true
false
~false
true
true & false
false
true | false
true
x = 5
y = 0
0
y += 2x
10
+=
: x += y
等同於x = x + y
,以下類推-=
*=
/=
\=
%=
^=
&=
|=
⊻=
(⊻: \xor
-tab)>>>=
>>=
<<=
if <判斷式>
<運算>
end
x = 0
y = 5
if x < y
println("x is less than y")
end
x is less than y
x = 10
y = 5
if x < y
println("x is less than y")
end
if x < y
println("x is less than y")
else
println("x is not less to y")
end
x is not less to y
if x < y
println("x is less than y")
elseif x > y
println("x is greater than y")
else
println("x is equal to y")
end
x is greater than y
if 1 # 數字不會自動轉成布林值
print("true")
end
TypeError: non-boolean (Int64) used in boolean context Stacktrace: [1] top-level scope at In[84]:1
if 3 > 5 && 5 == 5
println("This is not going to be printed.")
end
a && b
裡,如果 a
為 false
,就不需要考慮 b
了a || b
裡,如果 a
為 true
,就不需要考慮 b
了1 < 2 < 3
true
isfinite(5)
true
isinf(Inf)
true
isnan(NaN)
true
while <持續條件>
<運算>
end
a = 0
i = 1
while i <= 100
a += i
i += 1
end
a
5050
for i = 1:100
<運算>
end
a = 0
for i = 1:100
a += i
end
a
5050
字元是組成字串的基本單元
'A'
'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)
'a'
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
typeof('A')
Char
typeof("A")
String
Int('A')
65
Char(65)
'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)
Int('B')
66
'A' + 1
'B': ASCII/Unicode U+0042 (category Lu: Letter, uppercase)
'C' - 2
'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)
'C' > 'A'
true
'a' > 'A'
true
Int('a')
97
'a' - 'A'
32
x = "Hello World!"
"Hello World!"
"""Hello World!"""
"Hello World!"
"""Hello
World
!
"""
"Hello\nWorld\n!\n"
x[1]
'H': ASCII/Unicode U+0048 (category Lu: Letter, uppercase)
x[end-1]
'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)
x[3:5]
"llo"
s = "\u2200 x \U2203 y"
"∀ x ∃ y"
s[1]
'∀': Unicode U+2200 (category Sm: Symbol, math)
s[2]
StringIndexError("∀ x ∃ y", 2) Stacktrace: [1] string_index_err(::String, ::Int64) at ./strings/string.jl:12 [2] getindex_continued(::String, ::Int64, ::UInt32) at ./strings/string.jl:220 [3] getindex(::String, ::Int64) at ./strings/string.jl:213 [4] top-level scope at In[113]:1
nextind(s, 1)
4
s[4]
' ': ASCII/Unicode U+0020 (category Zs: Separator, space)
length("123456")
6
x = "Today"
y = "Sunday"
string(x, " is ", y)
"Today is Sunday"
"$x is $y"
"Today is Sunday"
"1 + 2 = $(1 + 2)"
"1 + 2 = 3"
"1 + 2 = 3" == "1 + 2 = $(1 + 2)"
true
occursin("banana", "na")
false
repeat(x, 10)
"TodayTodayTodayTodayTodayTodayTodayTodayTodayToday"
join(["apples", "bananas", "pineapples"], ", ", " and ")
"apples, bananas and pineapples"
當有些程式需要不斷被重複使用,只需要更改一部份程式碼即可
這些程式碼就可以被抽出來(abstract),成為 function
讓這部份程式可以有更廣泛的(generic)用處,而不是狹隘而特定的(specific)
function f(x, y)
return x + y
end
f (generic function with 1 method)
f(1, 2)
3
當你呼叫函式 f(1, 2)
的時候,x=1
與 y=2
會被傳送給 f
。
函式就會進行後續的運算,並把運算結果透過 return
進行回傳。
當函數被呼叫,記憶體會空出一塊空間給函式,是函式的運算空間。
f(f(1, 2), 3)
6
當以上函式被呼叫,最內部的函式 f(1, 2)
會先被運算,等運算結果回傳之後,才運算外層的函式 f(3, 3)
。
短小輕巧的函式在Julia很常見
h(x, y) = x + y
h (generic function with 1 method)
h(1, 2)
3
function g(x::Int64, y::Int64)::Int64
return x + y
end
g (generic function with 1 method)
g(1, 2)
3
g(1.2, 2.3)
MethodError: no method matching g(::Float64, ::Float64) Stacktrace: [1] top-level scope at In[131]:1
複製一份變數的值到函式中
e.g. C, primitive values in Java
在函式中製造一個參考(reference),參考指向變數
e.g. Python, object in Java
傳參數時,並不會複製一份給函式,但是參數本身會作為一個新的變數綁定(bind)到原本值的位址
println(objectid(1))
11967854120867199718
x = 1
println(objectid(x))
11967854120867199718
function sharing(x)
println(objectid(x))
x = 2
println(objectid(x))
end
sharing (generic function with 1 method)
sharing(x)
11967854120867199718 5352850025288631388
x
1
1 + 2 + 3 + 4 + 5 + 6
21
+(1, 2, 3, 4, 5, 6)
21
a = () -> println("Calling function a.")
#3 (generic function with 1 method)
a()
Calling function a.
b = x -> println(x)
#5 (generic function with 1 method)
b(5)
5
c = (x, y) -> x + y
#7 (generic function with 1 method)
c(2, 3)
5
x = (1, 2, 3)
(1, 2, 3)
x[1]
1
x[2:3]
(2, 3)
objectid(x)
0xedbeb2cfeb9b46ff
objectid(x[2:3])
0x1d867d66d42a6657
a, b, c = x
(1, 2, 3)
a
1
b
2
c
3
b, a = a, b
(1, 2)
a
2
b
1
h(1, 2)
3
return
keyword¶function sumproduct(x, y, z)
return (x + y) * z
end
sumproduct (generic function with 1 method)
function sumproduct(x, y, z)
(x + y) * z
end
sumproduct (generic function with 1 method)
function shuffle_(x, y, z)
(y, z, x)
end
shuffle_ (generic function with 1 method)
x = [1, 2, 3]
shuffle_(x...)
(2, 3, 1)
等價於 shuffle_(1, 2, 3)
適用 operators 跟 functions
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
x .^ 2
10-element Array{Int64,1}: 1 4 9 16 25 36 49 64 81 100
f(x) = 3x
f (generic function with 2 methods)
f.(x)
10-element Array{Int64,1}: 3 6 9 12 15 18 21 24 27 30