{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Numeric types\n", "\n", "\n", "First, let's focus on different and most basic (and useful for daily use) numerical types of objects in `Julia`.\n", "\n", "\n", "| Type|Desc. |Smallest number|Largest number|\n", "|-|-|-|-|\n", "|`Int8` | signed integers |$-2^7$| $2^7-1$|\n", "|`UInt8`| unsigned integers (_read:_ natural numbers)| $0$ | $2^8$|\n", "|`Int16` | signed integers |$-2^{15}$| $2^{15}-1$|\n", "|`UInt16`| unsigned integers (_read:_ natural numbers)| $0$ | $2^{16}$|\n", "|`Int64` | signed integers |$-2^{63}$| $2^{63}-1$|\n", "|`UInt64`| unsigned integers (_read:_ natural numbers)| $0$ | $2^{64}$|\n", "\n", "There is also an alias `Int` for integers with the default number of bits for your architecture (32 or 64).\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "x = 1" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{margin}\n", "\n", "For quiet execution of line `x = 1`, we should add `;` at the end of the line. \n", "This way the assignment will be made without printing the result.\n", "\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Int64" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "typeof(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can explicitly force `Julia` to set the precision of our integers:\n", "\n", "````{margin}\n", "```{note}\n", "In `Julia` we can use special unicode characters for naming objects, like `α` or even `αₖʲ`. In VS Code, to get `α` you have to type `\\alpha` and press `<tab>`. `αₖʲ` can be obtained by typing combination `\\alpha`, `<tab>`, `\\_k`, `<tab>`, `\\^j`, `<tab>`.\n", "```\n", "````" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "α = Int8(2)\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "127" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "Int8(2^7-1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "However, we have to remember about the ranges of used types:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "ename": "LoadError", "evalue": "InexactError: trunc(Int8, 256)", "output_type": "error", "traceback": [ "InexactError: trunc(Int8, 256)\n", "\n", "Stacktrace:\n", " [1] throw_inexacterror(f::Symbol, #unused#::Type{Int8}, val::Int64)\n", " @ Core ./boot.jl:602\n", " [2] checked_trunc_sint\n", " @ ./boot.jl:624 [inlined]\n", " [3] toInt8\n", " @ ./boot.jl:639 [inlined]\n", " [4] Int8(x::Int64)\n", " @ Core ./boot.jl:749\n", " [5] top-level scope\n", " @ In[41]:1\n", " [6] eval\n", " @ ./boot.jl:360 [inlined]\n", " [7] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)\n", " @ Base ./loading.jl:1094" ] } ], "source": [ "Int8(2^8) #Error message" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Unsigned integers are not super useful due to their default hexadecimal notation: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "UInt(1018) = 0x00000000000003fa\n" ] } ], "source": [ "@show UInt(1018);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Another type of numbers in `Julia` are floating-point values\n", "\n", "\n", "|Type|Number of bits|\n", "|--|--|\n", "|`Float16`| 16|\n", "|`Float32`| 32|\n", "|`Float64`| 64|\n", "\n", "\n", "Similarly to integers, `float` refers to floating-point values with the default number of bits for your architecture (32 or 64).\n", "\n", "```{margin}\n", "Notice the difference in letter capitalization: `float` vs. `Int`!\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.2" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "w = .2" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Float64" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "typeof(w)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Basic arithmetic operations" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On the surface, arithmetic operations (`+`, `-`, `*`, `/`) in `Julia` are very similar to the ones known from such languages as `Matlab`:\n", "\n", "```{margin}\n", "[Here](https://docs.julialang.org/en/v1/manual/mathematical-operations/) you can find the list of all standard built-in mathematical operations.\n", "```\n" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = 1\n", "y = 2\n", "x + y\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "For multiplication, we do not have to use `*` for unambiguous cases. `2.2*x` and `2.2x` will give the same results:\n", "\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3.3000000000000003" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = 1.5\n", "2.2x " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "However, I do not recommend it because in my opinion it makes the code a bit less legible.\n", "Besides, there are cases when it does not work:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "ename": "LoadError", "evalue": "UndefVarError: πx not defined", "output_type": "error", "traceback": [ "UndefVarError: πx not defined", "", "Stacktrace:", " [1] top-level scope", " @ :0", " [2] eval", " @ ./boot.jl:360 [inlined]", " [3] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)", " @ Base ./loading.jl:1094" ] } ], "source": [ "πx" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For presenting results of the operation macro `@show` can be quite useful:\n", "\n", "````{margin}\n", "A similar result can be obtained by using command `println`: \n", "\n", "```\n", " x = 1\n", " y = 2\n", " println(\"x + y + .2 is equal to $(x + y + .2)\")\n", "```\n", "\n", "`println` takes a string argument in quoes `\"`. Inside a string you can evaluate any `Julia` code inside `$(...)`.\n", "\n", "````" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x + y + 0.2 = 3.2\n" ] }, { "data": { "text/plain": [ "3.2" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "x = 1\n", "y = 2\n", "@show x + y + .2\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x + y + .2 is equal to 3.2\n" ] } ], "source": [ "x = 1\n", "y = 2\n", "println(\"x + y + .2 is equal to $(x + y + .2)\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can make several assignments in one line using separator `,`.\n", "Then, instead of three lines:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x = 12.3;\n", "y = 1;\n", "🤩 = -10;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "you can just use one line:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(12.3, 1, -10)" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "x, y, 🤩 = 12.3, 1, -10\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{margin}\n", "Yes, you can use emojis for naming objects in `Julia`. Nonetheless, you have to make sure that emojis are installed on the computer. \n", "This is rather the case for your own laptop but it is not so obious for UN*X distributions used on HPC clusters, which you may use at some point.\n", "Moreover, there is a documented problem with using emojis in Julia for VS Code.\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "🤩 = -10\n", "x = 12.3\n", "y = 1\n", "(y, x) = (1, 12.3)\n" ] }, { "data": { "text/plain": [ "(1, 12.3)" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "@show 🤩\n", "@show x\n", "@show y\n", "@show y, x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Operations (`+`, `-`, `*`, `/`, `\\`, `÷`, `%`, `^`) where one object is on both sides of the assignment operator (_e.g._, `x=x+1`) can be shortened:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x = 12.3\n", "x += 1 = 13.3\n", "x *= 2 = 26.6\n", "x ^= 2 = 707.5600000000001\n" ] } ], "source": [ "@show x;\n", "@show x += 1;\n", "@show x *= 2;\n", "@show x ^= 2;\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we combine two different numeric types, `Julia` will try to coerce the less general object to more general one: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "z = x + y = 42.964\n" ] }, { "data": { "text/plain": [ "Float64" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "x = Int(42)\n", "y = float(.964)\n", "@show z = x+y\n", "\n", "typeof(z)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can use also `Lisp`-like syntax (which we find in `R` as well. Sometimes this can be very useful, and other times, it can be quite [scary](https://twitter.com/mjskay/status/1454952248937783304)):" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "42.964" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "+(x, y)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(3 * (1 + 2)) ^ 5 = 59049\n" ] }, { "data": { "text/plain": [ "59049" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "@show ^(*( 3, +(1, 2) ), 5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are several ways to divide numbers. \n", "The most natural one is by using `/`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 / 2 = 0.5\n" ] }, { "data": { "text/plain": [ "0.5" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "@show 1/2 " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If for some reason, we want to use common fractions instead of decimals, then we have to use `//` instead:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1//2" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "1//2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Within common fractions, we can perform arithmetic operations:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 // 2 + 1 // 3 = 5//6\n" ] } ], "source": [ "@show 1//2+1//3;\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1 // 2) ^ 10 = 1//1024\n" ] } ], "source": [ "@show (1//2)^10;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But due to coercion in operations over different types, we might lose it:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 // 2 + 0.25 = 0.75\n", "1 // 2 + π = 3.641592653589793\n" ] } ], "source": [ "@show 1//2 + .25;\n", "@show 1//2 + π;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We perform integer division by using `div` or `÷` (to get this symbol type `\\div` and `<tab>`):" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "div(5, 3) = 1\n", "5 ÷ 3 = 1\n", "5 ÷ 3 = 1\n" ] } ], "source": [ "@show div(5,3);\n", "@show ÷(5,3);\n", "@show 5÷3;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We get remainder by using `rem` or `%`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "rem(5, 3) = 2\n", "5 % 3 = 2\n", "5 % 3 = 2\n" ] } ], "source": [ "@show rem(5,3);\n", "@show %(5,3);\n", "@show 5%3;" ] } ], "metadata": { "kernelspec": { "display_name": "Julia 1.6.0", "language": "julia", "name": "julia-1.6" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "1.6.0" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 }