{
 "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
}