Թվային տիպերը
Ինչպես ցանկացած ծրագրավորման լեզու, Elixir-ը նույնպես ունի թվային տիպեր։ Դրանք երկուսն են՝ ամբողջ թվեր (integer) և կոտորակային թվեր (float)։ Այս հոդվածում կծանոթանանք երկուսին էլ, ինչպես նաև դրանց հետ աշխատելու հիմնական գործողություններին։
Բոլոր օրինակները կարող եք փորձել iex-ում. պարզապես մուտքագրեք թիվը, և iex-ը կվերադարձնի դրա արժեքը՝
iex(1)> 42
42
iex(2)> 3.14
3.14
Ամբողջ թվեր
Ամբողջ թվերը գրվում են այնպես, ինչպես սովոր ենք՝ 0, 7, -15, 42։
Մեծ թվերն ավելի ընթեռնելի դարձնելու համար Elixir-ը թույլ է տալիս թվանշանների խմբերն իրարից բաժանել ընդգծման նշանով (_)՝
iex(1)> 1_000_000
1000000
1_000_000-ը և 1000000-ը միևնույն թիվն է. ընդգծման նշանը միայն մեր հարմարավետության համար է, կոմպիլյատորն այն անտեսում է։
Elixir-ի ամբողջ թվերն ունեն մի շատ հաճելի հատկություն. դրանք չունեն չափի սահմանափակում։ Շատ լեզուներում ամբողջ թվերը սահմանափակված են 32 կամ 64 բիթով, և այդ սահմանն անցնելիս սկսվում են խնդիրներ։ Elixir-ում կարող եք հանգիստ հաշվել, օրինակ, 2-ի հարյուրերորդ աստիճանը՝
iex(1)> 2 ** 100
1267650600228229401496703205376
Ամբողջ թվերն այլ հիմքերով
Առօրյայում մենք թվերը գրում ենք տասական հիմքով, բայց ծրագրավորման մեջ երբեմն ավելի հարմար են այլ հիմքերը։ Elixir-ում դրանք գրվում են հատուկ նախածանցներով․
- Երկուական (binary) —
0bնախածանցով․0b1101-ը տասական13-ն է - Ութական (octal) —
0oնախածանցով․0o52-ը տասական42-ն է - Տասնվեցական (hexadecimal) —
0xնախածանցով․0xF1-ը տասական241-ն է
iex(1)> 0b1101
13
iex(2)> 0o52
42
iex(3)> 0xF1
241
Ուշադրություն դարձրեք, որ iex-ը արդյունքը միշտ ցույց է տալիս տասական հիմքով. նախածանցները միայն թիվը գրելու այլընտրանքային ձևեր են, թիվն ինքնին հիշողության մեջ նույնն է։
Կոտորակային թվեր (floats)
Կոտորակային թվերը գրվում են տասնորդական տրոհիչով՝ 3.14, -0.5, 1.0։ Elixir-ում դրանք 64-բիթանոց են՝ կրկնակի ճշգրտությամբ (double precision)։ Այդ թվային տիպը սահմանված է IEEE 754 ստանդարտով, և կա համարյա բոլոր հայտնի ծրագրավորման լեզուներում (օրինակ C++, Java, C#, Python, JavaScript, Go։ Ի դեպ JavaScript-ում այն հիմնական թվային տիպն է, և օգտագործվում է նաև ամբողջ թվեր արտահայտելու համար։ Եվ չնայած որ լեզվի ստանդարտը ամբողջ թվերի համար ունի առանձին BigInt տիպ, պրակտիկ տեսանկյունից, առօրյա խնդիրների մեծամասնության համար ավելի հարմարավետ է double precision֊ի օգտագործումը)։
Երկու կարևոր կանոն․
1. Կետից առաջ և հետո պարտադիր պետք է թվանշան լինի։ Որոշ լեզուներում ընդունված .5 կամ 5. գրելաձևերը Elixir-ում սխալ են՝
iex(1)> 0.5 # ճիշտ է
0.5
iex(2)> .5 # սխալ է՝ SyntaxError
2. Շատ մեծ կամ շատ փոքր թվերի համար կարելի է օգտագործել գիտական (exponent) գրելաձևը։ e-ից հետո նշվում է 10-ի աստիճանը՝
iex(1)> 1.014523e10
10145230000.0
iex(2)> 5.2e-3
0.0052
Այսինքն՝ 1.014523e10 նշանակում է 1.014523 × 10¹⁰։
Ճշգրտության մասին
Float-ները մոտավոր արժեքներ են. սա վերաբերում է ոչ միայն Elixir-ին, այլև բոլոր այն ծրագրավորման լեզուներին, որոնք օգտագործում են IEEE 754 ստանդարտը։ Դասական օրինակը՝
iex(1)> 0.1 + 0.2
0.30000000000000004
Սա լեզվական սխալ (bug) չէ, այլ float-ների բնույթը. որոշ տասական կոտորակներ երկուական համակարգում ճշգրիտ ներկայացնել հնարավոր չէ։ Գործնական հետևությունը՝ երբ ճշգրտությունը կրիտիկական է (օրինակ՝ ֆինանսների, կոմերցիայի ոլորտներում), float-ների վրա հույս դնել չի կարելի։ Այդ դեպքերի լուծումներին կանդրադառնանք ավելի ուշ։
Թվաբանական գործողություններ
Հիմնական գործողությունները ծանոթ տեսք ունեն՝
iex(1)> 2 + 3
5
iex(2)> 10 - 4
6
iex(3)> 6 * 7
42
Բաժանման հետ կապված Elixir-ն ունի մի առանձնահատկություն, որին արժե ուշադրություն դարձնել. / օպերատորը միշտ վերադարձնում է float, նույնիսկ երբ երկու ամբողջ թվեր առանց մնացորդի են բաժանվում՝
iex(1)> 10 / 2
5.0
Եթե անհրաժեշտ է ամբողջ թվային բաժանում, օգտագործվում են div և rem ֆունկցիաները. div-ը վերադարձնում է քանորդը, rem-ը՝ մնացորդը՝
iex(1)> div(10, 3)
3
iex(2)> rem(10, 3)
1
Իսկ float-ից ամբողջ թիվ ստանալու համար կան round (կլորացնում է մոտակա ամբողջին) և trunc (պարզապես կտրում է կոտորակային մասը) ֆունկցիաները՝
iex(1)> round(3.7)
4
iex(2)> trunc(3.7)
3
Տիպի ստուգում
Երբեմն անհրաժեշտ է լինում ստուգել՝ արժեքը ամբո՞ղջ թիվ է, կոտորակայի՞ն, թե՞ ընդհանրապես թիվ։ Դրա համար կան is_integer, is_float և is_number ֆունկցիաները՝
iex(1)> is_integer(42)
true
iex(2)> is_float(42)
false
iex(3)> is_number(3.14)
true
Այս ֆունկցիաների իրական ուժը կբացահայտենք ավելի ուշ՝ pattern matching-ին և guard-երին ծանոթանալիս։
Փորձեք ինքներդ
Այս հոդվածում սովորածը ամրապնդելու համար լուծել ենք ծրագրավորման դասական FizzBuzz խնդիրը՝ numeric_types_fizzbuzz.exs։
Ֆայլում կհանդիպեք defmodule և def բառերին, որոնց դեռ չենք ծանոթացել․
առայժմ մի՛ կենտրոնացեք դրանց վրա։ Ուշադրություն դարձրեք միայն ֆունկցիայի
մարմնին, որտեղ խնդիրը լուծվում է հենց այս հոդվածում սովորած rem
ֆունկցիայի միջոցով։