diff --git a/agreg/Arithmetique_sur_les_posits.ipynb b/agreg/Arithmetique_sur_les_posits.ipynb index 6a098db..740f568 100644 --- a/agreg/Arithmetique_sur_les_posits.ipynb +++ b/agreg/Arithmetique_sur_les_posits.ipynb @@ -86,7 +86,7 @@ { "data": { "text/plain": [ - "val print : ('a, out_channel, unit) format -> 'a = \n" + "val print : ('a, out_channel, unit) format -> unit = \n" ] }, "execution_count": 2, @@ -96,9 +96,8 @@ ], "source": [ "let print f =\n", - " let r = Printf.printf f in\n", + " ignore (Printf.printf f);\n", " flush_all();\n", - " r\n", ";;" ] }, @@ -251,7 +250,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 38, "metadata": {}, "outputs": [ { @@ -260,7 +259,7 @@ "- : float = infinity\n" ] }, - "execution_count": 19, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" }, @@ -270,7 +269,7 @@ "- : float = neg_infinity\n" ] }, - "execution_count": 19, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" }, @@ -280,7 +279,7 @@ "- : float = nan\n" ] }, - "execution_count": 19, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" }, @@ -290,7 +289,7 @@ "- : float = infinity\n" ] }, - "execution_count": 19, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" }, @@ -300,7 +299,7 @@ "- : float = nan\n" ] }, - "execution_count": 19, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" }, @@ -310,7 +309,7 @@ "- : float = neg_infinity\n" ] }, - "execution_count": 19, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" }, @@ -320,20 +319,20 @@ "- : float = infinity\n" ] }, - "execution_count": 19, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(* Apparition de valeurs spéciales *)\n", - "1.0 /. 0.0;;\n", + "1.0 /. 0.0;;\n", "-1.0 /. 0.0;;\n", "infinity /. infinity;;\n", "\n", "(* Calcul étendu aux valeurs spéciales *)\n", "1.0 +. infinity;; (* absorbant ! *)\n", - "1.0 +. nan;; (* absorbant ! *)\n", + "1.0 +. nan;; (* absorbant ! *)\n", "(* Pareil pour -, *, / *)\n", "\n", "(* Changements de signe *)\n", @@ -399,7 +398,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Enfin, on rappelle que l'arithémtique sur les nombres réels n'est pas exacte, par exemple :" + "Enfin, on rappelle que l'arithmétique sur les nombres réels n'est pas exacte, par exemple :" ] }, { @@ -454,7 +453,7 @@ "metadata": {}, "source": [ "Les \"nombres universels\" (unum) ont été proposés par John Gustafson comme une autre manière pour la representation d'un nombre réel en utilisant un nombre fini de bits, afin d'être une alternative aux nombres flottants IEEE.\n", - "Cf. son excellent livre intitulé *The End of Error. Posits are a hardware-friendly version of unums.*, J. Gustafson, 2015.\n", + "Cf. son livre intitulé *The End of Error. Posits are a hardware-friendly version of unums.*, J. Gustafson, 2015.\n", "\n", "Un nombre flottant (IEEE 754) a un bit de signe, un ensemble de bits représentant l'exponent et un ensemble de bits appelés le significant (aussi désigné avec le nom \"mantisse\").\n", "Pour une taille donnée, la longueur des différentes parties est fixée et standardisée\n", @@ -484,8 +483,8 @@ "On dit qu'un tel nombre *posit* est un nombre `posit`.\n", "\n", "#### Bit de signe\n", - "Comme pour les flottants IEEE? le premier bit est le bit de signe.\n", - "S'il est $1$, le nombre est négatif, et on prend le complément à $2$ (*i.e.*, $0 \\mapsto 1, 1 \\mapsto 0$) de tous les bits suivants avant d'extraire les informations du reste des bits.\n", + "Comme pour les flottants IEEE, le premier bit est le bit de signe.\n", + "S'il est $1$, le nombre est négatif, et on prend le complément à $2$ (*i.e.*, $0 \\mapsto 1, 1 \\mapsto 0$ sur les bits) de tous les bits suivants avant d'extraire les informations du reste des bits.\n", "\n", "#### Bits de régime\n", "Après le bit de signe suit les bits de régime, dont le nombre est variable.\n", @@ -526,7 +525,7 @@ "\n", "$$u = 2^{2^{es}}.$$\n", "\n", - "L'exposant $e$ est ensuite simplement un entier non signé obtenu en interprétant les bits de l'exposant, avec le bit de poids faible en dernier (comme un nombre binaire classique).\n", + "L'exposant $e$ est ensuite simplement un entier non signé obtenu en interprétant les bits de l'exposant, avec le bit de poids faible *en dernier* (comme un nombre binaire classique) − ce qu'on désigne souvent par \"little endian\", la petite fin.\n", "\n", "La fraction $f$ est $1 +$ les bits de fraction interprétés comme s'ils suivent une virgule en binaire. Par exemple, si les bits de fraction sont $10011$, alors $f = 1.10011$ en binaire.\n", "\n", @@ -577,7 +576,7 @@ "\n", "- Question : cela n'est pas le cas pour les flottants IEEE ?\n", "\n", - "Pour des *posits* `posit`, la plus grande valeur finie représentable est notée $\\mathrm{maxpos}$. Cette valeur est obtenue quand $k$ est aussi grand que possible as, *i.e.*, quand tous les bits après le bit de signe sont des $1$\n", + "Pour des *posits* `posit`, la plus grande valeur finie représentable est notée $\\mathrm{maxpos}$. Cette valeur est obtenue quand $k$ est aussi grand que possible as, *i.e.*, quand tous les bits après le bit de signe sont des $1$.\n", "Dans ce cas, $k=n-2$, donc $\\mathrm{maxpos}$ vaut\n", "\n", "$$u^{n-2} = \\left( 2^{2^{es} } \\right)^{n-2}.$$\n", @@ -589,7 +588,7 @@ "\n", "L'amplitude dynamique est\n", "\n", - "$$\\log_{10}\\left( 2^{2^{e} } \\right)^{2n-4} = (2n-4)2^{es}\\log_{10}2.$$\n", + "$$\\log_{10}\\left( 2^{2^{e} } \\right)^{2n-4} = (2n-4) \\times 2^{es}\\times \\log_{10}2.$$\n", "\n", "Par exemple, des *posits* sur $16$ bits avec `es`$=1$ ont une amplitude dynamique de $17$ décades, alors que des flottants IEEE sur $16$ bits ont une amplitude de $12$ décades.\n", "\n", @@ -613,7 +612,9 @@ { "cell_type": "markdown", "metadata": {}, - "source": [] + "source": [ + "FIXME" + ] }, { "cell_type": "markdown", @@ -623,13 +624,17 @@ "\n", "Il n'y pas grand chose à dire, les posits gagnent carrément !\n", "\n", + "Il faut que j'ajoute de la théorie !\n", + "\n", "> [Inspiré par ce post de blog](https://www.johndcook.com/blog/2018/04/14/ieee-vs-posit/)" ] }, { "cell_type": "markdown", "metadata": {}, - "source": [] + "source": [ + "![comparaison_floats_vs_posits_under_stereographic_projection.png 50%](images/comparaison_floats_vs_posits_under_stereographic_projection.png)" + ] }, { "cell_type": "markdown", @@ -639,26 +644,21 @@ "> [Inspiré par ce post de blog](https://www.johndcook.com/blog/2018/04/15/eight-bit-floating-point/)" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "markdown", "metadata": {}, "source": [ - "![figures/eight_bit_ieee2.png](figures/eight_bit_ieee2.png)\n", - "![figures/eight_bit_ieee2.png](figures/eight_bit_posit2.png)\n", + "![images/eight_bit_ieee2.png](images/eight_bit_ieee2.png)\n", + "![images/eight_bit_ieee2.png](images/eight_bit_posit2.png)\n", "https://www.johndcook.com/eight_bit_posit2.png" ] }, { "cell_type": "markdown", "metadata": {}, - "source": [] + "source": [ + "FIXME" + ] }, { "cell_type": "markdown", @@ -668,10 +668,11 @@ "\n", "TODO à rédiger\n", "\n", - "Dans cette partie, nous considérons les calculs sur les *posits*.\n", + "Dans cette partie, nous considérons les calculs directement implémentés sur les *posits*.\n", "\n", - "Une première approche consiste à transformer les *posits* en nombre flottants, et utiliser les opérations classiques sur les *posits*, puis à convertir le résultat.\n", + "Une première approche consiste à transformer les *posits* en nombres flottants, et utiliser les opérations classiques sur les *posits*, puis à convertir le résultat flottant en un *posit*.\n", "\n", + "- Question : à `n` et `es` fixés, peut-on convertir un flottant en un *posit* ? De façon unique ? Décrivez l'algorithme.\n", "- Question : cela peut-il fonctionner ? Peut-on espérer garder les avantages décrits plus hauts si on se limite à cette approche naïve ?\n", "\n", "Proposer des algorithmes qui permettent de calculer les opérations suivantes, pour des *posits* $x$ et $y$ qui partagent le même format `posit` :\n", @@ -708,8 +709,10 @@ }, { "cell_type": "code", - "execution_count": 50, - "metadata": {}, + "execution_count": 3, + "metadata": { + "scrolled": true + }, "outputs": [ { "data": { @@ -717,7 +720,7 @@ "type bits = bool array\n" ] }, - "execution_count": 50, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -728,7 +731,7 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -737,15 +740,15 @@ "type posit = { es : int; n : int; b : bits; }\n" ] }, - "execution_count": 51, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type posit = {\n", - " es : int;\n", - " n : int;\n", + " es : int; (* prend de la place en plus ! *)\n", + " n : int; (* mais simplifie l'écriture des fonctions *)\n", " b : bits;\n", "};;" ] @@ -755,7 +758,7 @@ "metadata": {}, "source": [ "> Est-ce que ça coûte très cher de stocker aussi `n` et `es` ?\n", - "> A priori non, parce que pour un *posit* de 32 bits, `b` occupe 32 bits et `n` et `es` sont majorés par $\\log_2(32)$ donc occupe 10 bits au maximum à eux deux. C'est un sur-coût raisonnable pour notre approche.\n", + "> A priori non, parce que pour un *posit* de 32 bits, `b` occupe 32 bits et `n` et `es` sont majorés par $\\log_2(32) = 5$ donc occupe $2 \\times 5 = 10$ bits au maximum à eux deux. C'est un sur-coût raisonnable pour notre approche.\n", ">\n", "> En pratique, on l'a dit, on choisirait `n` et `es` *une bonne fois pour toute* pour une certaine application." ] @@ -781,7 +784,7 @@ }, { "cell_type": "code", - "execution_count": 119, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -790,7 +793,7 @@ "val signe_of_posit : posit -> int = \n" ] }, - "execution_count": 119, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -803,7 +806,7 @@ }, { "cell_type": "code", - "execution_count": 157, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -812,7 +815,7 @@ "val echange_bits : bits -> int -> bits = \n" ] }, - "execution_count": 157, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -829,7 +832,7 @@ }, { "cell_type": "code", - "execution_count": 158, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -838,7 +841,7 @@ "val echange_bits_apres_le_premier : posit -> posit = \n" ] }, - "execution_count": 158, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -847,7 +850,8 @@ "let echange_bits_apres_le_premier (p : posit) : posit =\n", " if p.b.(0) then\n", " { p with b = echange_bits p.b 1 }\n", - " else { p with b = Array.copy p.b }\n", + " else\n", + " { p with b = Array.copy p.b }\n", ";;" ] }, @@ -860,7 +864,7 @@ }, { "cell_type": "code", - "execution_count": 159, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -869,7 +873,7 @@ "val regime_of_posit : posit -> int = \n" ] }, - "execution_count": 159, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -879,8 +883,8 @@ " let premier_bit_regime = p.b.(1) in\n", " let encore_les_memes_bits = ref true in\n", " let m = ref 1 in\n", - " while !encore_les_memes_bits\n", - " && !m <= p.n - 1 do\n", + " while !encore_les_memes_bits && !m <= p.n - 1\n", + " do\n", " if p.b.(!m + 1) <> premier_bit_regime then\n", " encore_les_memes_bits := false\n", " else\n", @@ -903,7 +907,7 @@ }, { "cell_type": "code", - "execution_count": 160, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -912,7 +916,7 @@ "val uint_of_bits : bits -> int = \n" ] }, - "execution_count": 160, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -947,7 +951,28 @@ }, { "cell_type": "code", - "execution_count": 161, + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "val t : bool = true\n", + "val f : bool = false\n" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "let t = true and f = false;;" + ] + }, + { + "cell_type": "code", + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -956,13 +981,13 @@ "- : int = 0\n" ] }, - "execution_count": 161, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "uint_of_bits [|false; false; false|];;" + "uint_of_bits [|f; f; f|];;" ] }, { @@ -974,7 +999,7 @@ }, { "cell_type": "code", - "execution_count": 162, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -983,18 +1008,18 @@ "- : int = 4\n" ] }, - "execution_count": 162, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "uint_of_bits [|true; false; false|];;" + "uint_of_bits [|t; f; f|];;" ] }, { "cell_type": "code", - "execution_count": 163, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -1003,18 +1028,18 @@ "- : int = 6\n" ] }, - "execution_count": 163, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "uint_of_bits [|true; true; false|];;" + "uint_of_bits [|t; t; f|];;" ] }, { "cell_type": "code", - "execution_count": 164, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -1023,18 +1048,18 @@ "- : int = 1\n" ] }, - "execution_count": 164, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "uint_of_bits [|false; false; true|];;" + "uint_of_bits [|f; f; t|];;" ] }, { "cell_type": "code", - "execution_count": 165, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -1043,13 +1068,13 @@ "- : int = 7\n" ] }, - "execution_count": 165, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "uint_of_bits [|true; true; true|];;" + "uint_of_bits [|t; t; t|];;" ] }, { @@ -1063,27 +1088,7 @@ }, { "cell_type": "code", - "execution_count": 166, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "- : 'a array -> int -> int -> 'a array = \n" - ] - }, - "execution_count": 166, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "Array.sub" - ] - }, - { - "cell_type": "code", - "execution_count": 167, + "execution_count": 20, "metadata": {}, "outputs": [ { @@ -1092,7 +1097,7 @@ "val exposant_of_posit : posit -> int -> int * int = \n" ] }, - "execution_count": 167, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -1133,18 +1138,18 @@ }, { "cell_type": "code", - "execution_count": 168, + "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "File \"[168]\", line 1, characters 23-24:\n", + "File \"[21]\", line 1, characters 23-24:\n", "Warning 27: unused variable p.\n", - "File \"[168]\", line 1, characters 35-36:\n", + "File \"[21]\", line 1, characters 35-36:\n", "Warning 27: unused variable m.\n", - "File \"[168]\", line 1, characters 45-60:\n", + "File \"[21]\", line 1, characters 45-60:\n", "Warning 27: unused variable taille_exposant.\n" ] }, @@ -1154,7 +1159,7 @@ "val fraction_of_posit : posit -> int -> int -> float = \n" ] }, - "execution_count": 168, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -1176,7 +1181,7 @@ }, { "cell_type": "code", - "execution_count": 169, + "execution_count": 22, "metadata": {}, "outputs": [ { @@ -1185,20 +1190,18 @@ "val carre : int -> int = \n" ] }, - "execution_count": 169, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "let carre (x : int) : int =\n", - " x * x\n", - ";;" + "let carre (x : int) : int = x * x;;" ] }, { "cell_type": "code", - "execution_count": 170, + "execution_count": 23, "metadata": {}, "outputs": [ { @@ -1207,7 +1210,7 @@ "val expo_int : int -> int -> int = \n" ] }, - "execution_count": 170, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -1231,7 +1234,7 @@ }, { "cell_type": "code", - "execution_count": 171, + "execution_count": 24, "metadata": { "scrolled": true }, @@ -1242,7 +1245,7 @@ "- : int = 2\n" ] }, - "execution_count": 171, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" }, @@ -1252,7 +1255,7 @@ "- : int = 4\n" ] }, - "execution_count": 171, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" }, @@ -1262,7 +1265,7 @@ "- : int = 8\n" ] }, - "execution_count": 171, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" }, @@ -1272,7 +1275,7 @@ "- : int = 16\n" ] }, - "execution_count": 171, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } @@ -1293,7 +1296,7 @@ }, { "cell_type": "code", - "execution_count": 172, + "execution_count": 25, "metadata": {}, "outputs": [ { @@ -1302,7 +1305,7 @@ "- : int -> int -> int = \n" ] }, - "execution_count": 172, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -1313,7 +1316,7 @@ }, { "cell_type": "code", - "execution_count": 173, + "execution_count": 26, "metadata": {}, "outputs": [ { @@ -1322,7 +1325,7 @@ "- : int = 2\n" ] }, - "execution_count": 173, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" }, @@ -1332,7 +1335,7 @@ "- : int = 4\n" ] }, - "execution_count": 173, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" }, @@ -1342,7 +1345,7 @@ "- : int = 8\n" ] }, - "execution_count": 173, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" }, @@ -1352,7 +1355,7 @@ "- : int = 16\n" ] }, - "execution_count": 173, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -1375,7 +1378,7 @@ }, { "cell_type": "code", - "execution_count": 174, + "execution_count": 27, "metadata": {}, "outputs": [ { @@ -1384,7 +1387,7 @@ "- : ('a -> bool) -> 'a array -> bool = \n" ] }, - "execution_count": 174, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" } @@ -1395,7 +1398,7 @@ }, { "cell_type": "code", - "execution_count": 175, + "execution_count": 29, "metadata": {}, "outputs": [ { @@ -1404,7 +1407,7 @@ "val est_nul : posit -> bool = \n" ] }, - "execution_count": 175, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } @@ -1417,7 +1420,7 @@ }, { "cell_type": "code", - "execution_count": 176, + "execution_count": 30, "metadata": {}, "outputs": [ { @@ -1426,7 +1429,7 @@ "val est_infini : posit -> bool = \n" ] }, - "execution_count": 176, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } @@ -1444,37 +1447,112 @@ "#### Mettre tout ça ensemble" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "On va commencer par écrire une fonction qui affiche un `posit`, pour aider au débogage de la suite." + ] + }, + { + "cell_type": "code", + "execution_count": 103, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "val print_posit : posit -> unit = \n" + ] + }, + "execution_count": 103, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "let print_posit (p : posit) : unit =\n", + " Format.printf \"\\nposit<%i,%i> \" p.n p.es;\n", + " Array.iter (fun a -> Format.printf (if a then \"1\" else \"0\")) p.b;\n", + " flush_all();\n", + ";;" + ] + }, { "cell_type": "code", - "execution_count": 177, + "execution_count": 106, "metadata": {}, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "posit<10,1> 0111100000000000\n" + ] + }, { "data": { "text/plain": [ - "val posit_to_float : posit -> float = \n" + "- : unit = ()\n" ] }, - "execution_count": 177, + "execution_count": 106, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print_posit p2;;" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Et enfin on assemble le tout :" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "val posit_to_float : ?debogue:bool -> posit -> float = \n" + ] + }, + "execution_count": 107, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(** Complexité linéaire dans la taille des bits de p *)\n", - "let posit_to_float (p : posit) : float =\n", + "let posit_to_float ?(debogue=false) (p : posit) : float =\n", + " if debogue then print_posit p;\n", " (* Bit de signe *)\n", " let signe = signe_of_posit p in\n", + " if debogue then Format.printf \"\\nSigne %i\" signe; flush_all();\n", " (* On doit inverser les bits suivant si le nombre est négatif *)\n", " let p2 = echange_bits_apres_le_premier p in\n", + " if debogue then print_posit p2;\n", " (* Bits de régime *)\n", " let k = regime_of_posit p2 in\n", + " if debogue then Format.printf \"\\nRegime %i\" k; flush_all();\n", " (* Taille du régime *)\n", " let m = if k < 0 then -k else k + 1 in\n", + " if debogue then Format.printf \"\\nTaille du regime %i\" m; flush_all();\n", " (* Bits de l'exposant *)\n", " let exposant, taille_exposant = exposant_of_posit p2 m in\n", + " if debogue then Format.printf \"\\nExposant %i\" exposant; flush_all();\n", + " if debogue then Format.printf \"\\nTaille de l'exposant %i\" taille_exposant; flush_all();\n", " (* Bits de la fraction *)\n", " let fraction = fraction_of_posit p2 m taille_exposant in\n", + " if debogue then Format.printf \"\\nFraction %g\" fraction; flush_all();\n", " (* Gestion de l'infini *)\n", " if est_infini p then infinity\n", " else begin\n", @@ -1499,28 +1577,7 @@ }, { "cell_type": "code", - "execution_count": 197, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "val f : bool = false\n", - "val t : bool = true\n" - ] - }, - "execution_count": 197, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "let f = false and t = true;;" - ] - }, - { - "cell_type": "code", - "execution_count": 198, + "execution_count": 108, "metadata": {}, "outputs": [ { @@ -1530,7 +1587,7 @@ "val es : int = 1\n" ] }, - "execution_count": 198, + "execution_count": 108, "metadata": {}, "output_type": "execute_result" } @@ -1548,7 +1605,7 @@ }, { "cell_type": "code", - "execution_count": 199, + "execution_count": 110, "metadata": {}, "outputs": [ { @@ -1561,29 +1618,43 @@ " false; false; false; false; false; false|]}\n" ] }, - "execution_count": 199, + "execution_count": 110, "metadata": {}, "output_type": "execute_result" }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fraction 1\n", + "posit<10,1> 0000000000000000\n", + "Signe 1\n", + "posit<10,1> 0000000000000000\n", + "Regime -10\n", + "Taille du regime 10\n", + "Exposant 0\n", + "Taille de l'exposant 1\n" + ] + }, { "data": { "text/plain": [ "- : float = 0.\n" ] }, - "execution_count": 199, + "execution_count": 110, "metadata": {}, "output_type": "execute_result" } ], "source": [ "let p1 = { n = n; es = es; b = [|f;f;f;f;f;f;f;f;f;f;f;f;f;f;f;f|] };;\n", - "let _ = posit_to_float p1;;" + "let _ = posit_to_float ~debogue:true p1;;" ] }, { "cell_type": "code", - "execution_count": 200, + "execution_count": 111, "metadata": {}, "outputs": [ { @@ -1596,24 +1667,38 @@ " false; false; false; false; false; false|]}\n" ] }, - "execution_count": 200, + "execution_count": 111, "metadata": {}, "output_type": "execute_result" }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fraction 1\n", + "posit<10,1> 1000000000000000\n", + "Signe -1\n", + "posit<10,1> 1111111111111111\n", + "Regime 9\n", + "Taille du regime 10\n", + "Exposant 1\n", + "Taille de l'exposant 1\n" + ] + }, { "data": { "text/plain": [ "- : float = infinity\n" ] }, - "execution_count": 200, + "execution_count": 111, "metadata": {}, "output_type": "execute_result" } ], "source": [ "let p2 = { n = n; es = es; b = [|t;f;f;f;f;f;f;f;f;f;f;f;f;f;f;f|] };;\n", - "let _ = posit_to_float p2;;" + "let _ = posit_to_float ~debogue:true p2;;" ] }, { @@ -1627,99 +1712,177 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "- Positif, avec un régime de $1$ et de longueur 4 (donc $m=k-1=3$) :" + "- Positif, avec un régime de $1$ et de longueur 4 (donc $m=k-1=3$), tous les autres bits à $0$, on obtient le nombre $(-1)^0 * 1.0 * 2^{0 + 3*2^1} = 64$ :" ] }, { "cell_type": "code", - "execution_count": 201, + "execution_count": 115, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "val p2 : posit =\n", + "val p3 : posit =\n", " {es = 1; n = 10;\n", " b =\n", " [|false; true; true; true; true; false; false; false; false; false;\n", " false; false; false; false; false; false|]}\n" ] }, - "execution_count": 201, + "execution_count": 115, "metadata": {}, "output_type": "execute_result" }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fraction 1\n", + "posit<10,1> 0111100000000000\n", + "Signe 1\n", + "posit<10,1> 0111100000000000\n", + "Regime 3\n", + "Taille du regime 4\n", + "Exposant 0\n", + "Taille de l'exposant 1\n" + ] + }, { "data": { "text/plain": [ "- : float = 64.\n" ] }, - "execution_count": 201, + "execution_count": 115, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "let p2 = { n = n; es = es;\n", + "let p3 = { n = n; es = es;\n", " b = [|f; t;t;t;t; f; f; f;f;f;f;f;f;f;f;f|]\n", " (* signe regime4t sepa expo fraction *)\n", "};;\n", - "let _ = posit_to_float p2;;" + "let _ = posit_to_float ~debogue:true p3;;" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- Positif, avec un régime de $1$ et de longueur 4 (donc $m=k-1=3$), un exposant à $1$ et tous les autres bits à $0$, on obtient le nombre $(-1)^0 * 1.0 * 2^{1 + 3*2^1} = 128$ :" ] }, { "cell_type": "code", - "execution_count": 202, + "execution_count": 119, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "val s : int = 1\n" + "val p4 : posit =\n", + " {es = 1; n = 10;\n", + " b =\n", + " [|false; true; true; true; true; false; true; false; false; false; false;\n", + " false; false; false; false; false|]}\n" ] }, - "execution_count": 202, + "execution_count": 119, "metadata": {}, "output_type": "execute_result" }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fraction 1\n", + "posit<10,1> 0111101000000000\n", + "Signe 1\n", + "posit<10,1> 0111101000000000\n", + "Regime 3\n", + "Taille du regime 4\n", + "Exposant 1\n", + "Taille de l'exposant 1\n" + ] + }, { "data": { "text/plain": [ - "val m : int = 3\n" + "- : float = 128.\n" ] }, - "execution_count": 202, + "execution_count": 119, "metadata": {}, "output_type": "execute_result" - }, + } + ], + "source": [ + "let p4 = { n = n; es = es;\n", + " b = [|f; t;t;t;t; f; t; f;f;f;f;f;f;f;f;f|]\n", + " (* signe regime4t sepa expo fraction *)\n", + "};;\n", + "let _ = posit_to_float ~debogue:true p4;;" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- Si on change `es` la taille maximale de l'exposant, on voit qu'on peut atteindre des nombres plus grands. Positif, avec un régime de $1$ et de longueur 4 (donc $m=k-1=3$), un exposant à $11_2 = 3$ (lu en binaire !) et tous les autres bits à $0$, on obtient le nombre $(-1)^0 * 1.0 * 2^{3 + 3*2^2} = 32768$ :" + ] + }, + { + "cell_type": "code", + "execution_count": 121, + "metadata": {}, + "outputs": [ { "data": { "text/plain": [ - "val e : int = 0\n", - "val te : int = 1\n" + "val p5 : posit =\n", + " {es = 2; n = 10;\n", + " b =\n", + " [|false; true; true; true; true; false; true; true; false; false; false;\n", + " false; false; false; false; false|]}\n" ] }, - "execution_count": 202, + "execution_count": 121, "metadata": {}, "output_type": "execute_result" }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Fraction 1\n", + "posit<10,2> 0111101100000000\n", + "Signe 1\n", + "posit<10,2> 0111101100000000\n", + "Regime 3\n", + "Taille du regime 4\n", + "Exposant 3\n", + "Taille de l'exposant 2\n" + ] + }, { "data": { "text/plain": [ - "val fr : float = 1.\n" + "- : float = 32768.\n" ] }, - "execution_count": 202, + "execution_count": 121, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "let s = signe_of_posit p2;;\n", - "let m = regime_of_posit p2;;\n", - "let e, te = exposant_of_posit p2 m;;\n", - "let fr = fraction_of_posit p2 m te;;" + "let p5 = { n = n; es = 2;\n", + " b = [|f; t;t;t;t; f; t;t; f;f;f;f;f;f;f;f|]\n", + " (* signe regime4t sepa expo fraction *)\n", + "};;\n", + "let _ = posit_to_float ~debogue:true p5;;" ] }, { diff --git a/agreg/images/eight_bit_ieee2.png b/agreg/images/eight_bit_ieee2.png new file mode 100644 index 0000000..d04084a Binary files /dev/null and b/agreg/images/eight_bit_ieee2.png differ diff --git a/agreg/images/eight_bit_posit2.png b/agreg/images/eight_bit_posit2.png new file mode 100644 index 0000000..63462c8 Binary files /dev/null and b/agreg/images/eight_bit_posit2.png differ