- Fichier base.lua.
Code : Tout sélectionner
function divmod(a,b) local q = 0 local r = a while not (r < b) do q = q+1 r = r-b end return q,r end function base_core(n,b) local q,r = divmod(n,b) local digits = {r} while not (q == 0) do q,r = divmod(q,b) table.insert(digits,1,r) end return digits end function base(n,b) if (b > 1) then local digits_core = base_core(n,b) if not (b > 10) then local digits = '' for k=1,#digits_core do digits = digits .. tostring(digits_core[k]) end return digits elseif not (b > 36) then local digits = '' for k=1,#digits_core do digits = digits .. string.sub('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',digits_core[k]+1,digits_core[k]+1) end return digits else local digits = '[' for k=1,#digits_core-1 do digits = digits .. tostring(digits_core[k]) .. ';' end return digits .. tostring(digits_core[#digits_core]) .. ']' end end end
- Fichier exemple.tex.
Code : Tout sélectionner
\documentclass{article} \directlua{require("base")} \newcommand{\base}[2]{\directlua{tex.sprint(base(#1,#2))}} \begin{document} \begin{center} \begin{tabular}{ccccc} \texttt{\base{123}{2}} & \texttt{\base{12345}{8}} & \texttt{\base{12345}{12}} & \texttt{\base{1234567}{20}} & \texttt{\base{123456789}{60}} \\ \end{tabular} \end{center} \end{document}
- Résultat obtenu après compilation lualatex.
[Lualatex] Bases de numération
-
- Administrateur
- Messages : 7977
- Inscription : samedi 28 mai 2005, 14:23
- Statut actuel : Enseignant
[Lualatex] Bases de numération
Bonjour, voici un exemple d'utilisation de lualatex, permettant l'écriture de nombres entiers dans différentes bases de numération.
-
- Administrateur
- Messages : 7977
- Inscription : samedi 28 mai 2005, 14:23
- Statut actuel : Enseignant
Re: [Lualatex] Bases de numération
On peut par exemple adapter la macro
On obtient alors le résultat suivant.
\base
afin d'indiquer la base utilisée.Code : Tout sélectionner
\documentclass{article}
\directlua{require("base")}
\newcommand{\base}[2]{\ensuremath{\texttt{\directlua{tex.sprint(base(#1,#2))}_{#2}}}}
\begin{document}
\begin{center}
\begin{tabular}{ccccc}
\base{123}{2} &
\base{12345}{8} &
\base{12345}{12} &
\base{1234567}{20} &
\base{123456789}{60} \\
\end{tabular}
\end{center}
\end{document}
-
- Utilisateur chevronné
- Messages : 2200
- Inscription : samedi 29 décembre 2007, 00:58
Re: [Lualatex] Bases de numération
Coïncidence quantique... Je finis de faire un truc sur ce sujet que je mettrais dans ce fil sous peu... Ou pas ! 

-
- Utilisateur chevronné
- Messages : 2200
- Inscription : samedi 29 décembre 2007, 00:58
Re: [Lualatex] Bases de numération
Une petite amélioration même si j'estime que mon code reste un prototype de type "PdC" (Preuve du Concept). Il devrait rester des bugs ... Ou pas.
C'est sous licence GPL... Et plus tard sur github quand j'aurais le temps.

C'est sous licence GPL... Et plus tard sur github quand j'aurais le temps.
Code de basedigits.lua
Code : Tout sélectionner
----------------
-- MATH TOOLS --
----------------
function intlog(nb, base)
if nb < base then
return 0
end
local power = 0
local q, _ = divmod(nb, base)
while q >= base do
power = power + 1
q, r = divmod(q, base)
end
power = power + 1
return power
end
function divmod(a, b)
local r = a % b
local q = math.floor((a - r) / b)
return q, r
end
function nbtodigits(nb, base)
-- Small integer --
if nb < base then
return {nb}, {nil}
end
-- At least one division is needed --
local q, r = divmod(nb, base)
local digits = {r}
local quotients = {q}
-- Intermediate calculations --
while q >= base do
q, r = divmod(q, base)
table.insert(digits , 1, r)
table.insert(quotients, 1, q)
end
table.insert(digits , 1, q)
table.insert(quotients, 1, nil)
return digits, quotients
end
function digitstonb(digits, base)
local nb = 0
for _, d in pairs(digits) do
nb = base * nb + d
end
return nb
end
-----------------------------------
-- B-WRITING OF A DECIMAL NUMBER --
-----------------------------------
function digits(nb, base)
local digits, _ = nbtodigits(nb, base)
return display_inline(digits, base)
end
function display_inline(digits, base)
local text = '('
local sep = (base >= 10 and '{\\cdot}') or ''
for k, d in pairs(digits) do
d = tostring(d)
text = text .. d
if k < #digits then
text = text .. sep
end
end
text = text .. ')_{' .. tostring(base) .. '}'
return text
end
--------------------------------------------
-- CALCULATE THE B-DIGITS USING DIVISIONS --
--------------------------------------------
NEWLINE = '\\\\'
function divtodigits(nb, base)
local digits, quotients = nbtodigits(nb, base)
-- nb < base --
if nb < base then
return ''
end
-- Variables used to type the table --
local content = ''
-- 1st row --
content = '&' .. tostring(nb) .. NEWLINE
-- "Step" rows --
for k = #digits, 2, -1 do
content = content .. tostring(digits[k]) .. '&' .. tostring(quotients[k])
if k > 2 then
content = content .. NEWLINE
end
end
-- The arrow --
arrow = '\\CodeAfter'
arrow = arrow .. '\\begin{tikzpicture}'
arrow = arrow .. '\\draw[red, rounded corners, ->]([yshift=-7pt]'
arrow = arrow .. tostring(#digits) .. '-2.south) -| ([xshift=-7pt]2-1.west);'
arrow = arrow .. '\\end{tikzpicture}'
-- Nothing left to do --
local head = '\\begin{NiceTabular}{r|ll}'
local tail = '\\end{NiceTabular}'
return head
.. content
.. arrow
.. tail
end
-----------------------------------------
-- CALCULATE THE B-DIGITS USING POWERS --
-----------------------------------------
function powertodigits(nb, base)
-- nb < base --
if nb < base then
return ''
end
local N_log = intlog(nb, base)
local strbase = tostring(base)
local content = ''
-- Table of powers --
content = content
.. '\\begin{NiceTabular}{c*{' .. tostring(N_log + 1) .. '}{|c}}'
local power_row = ''
local value_row = ''
local power = 1
for k = 0, N_log + 1, 1 do
power_row = power_row .. '$' .. strbase .. '^{' .. tostring(k) .. '}$'
value_row = value_row .. '$' .. tostring(power) .. '$'
if k <= N_log then
power_row = power_row .. '&'
value_row = value_row .. '&'
end
power = power * base
end
content = content
.. power_row
.. NEWLINE .. '\\hline'
.. value_row
.. '\\end{NiceTabular}'
-- Step by step calcluations --
content = content
.. '\\par\\medskip'
.. '$\\begin{WithArrows}'
local nb_ = nb
local power_sum = ''
local power_k, coef
for k = N_log, 0, -1 do
power = math.floor(base^k)
if nb_ ~=0 and power <= nb_ then
power_k = strbase .. '^' ..tostring(k)
if k ~= N_log then
content = content .. '='
end
content = content .. '&\\,\\,'
if power_sum ~= '' then
content = content .. power_sum .. ' + '
end
content = content
.. tostring(nb_)
.. '\\Arrow{$' .. tostring(power) .. ' = ' .. power_k .. '$}'
.. NEWLINE
coef = 0
while power <= nb_ do
coef = coef + 1
nb_ = nb_ - power
end
if coef == 1 then
coef = ''
else
coef = tostring(coef) .. '\\cdot'
end
if power_sum == '' then
power_sum = coef .. power_k
else
power_sum = power_sum .. ' + ' .. coef .. power_k
end
end
end
content = content
.. '=&\\,\\,' .. power_sum
.. NEWLINE
.. '=&\\,\\,' .. digits(nb, base)
.. '\\end{WithArrows}$'
-- Nothing left to do --
return content
end
Doc. TeX de test
Code : Tout sélectionner
\documentclass{article}
\usepackage{tikz}
\usepackage{nicematrix}
\usepackage{witharrows}
\directlua{dofile('basedigits.lua')}
\newcommand\digits[2]{\directlua{tex.sprint(digits(#1,#2))}}
\newcommand\divtodigits[2]{\directlua{tex.sprint(divtodigits(#1,#2))}}
\newcommand\powertodigits[2]{\directlua{tex.sprint(powertodigits(#1,#2))}}
\newcommand\test[2]{
$#1$ en base $#2$ : $\digits{#1}{#2}$
\divtodigits{#1}{#2}
\medskip
\powertodigits{#1}{#2}
}
\begin{document}
\begin{itemize}
\item \test{77}{2}
\item \test{127}{2}
\newpage
\item \test{33}{3}
\item \test{33}{16}
\item \test{12}{16}
\end{itemize}
\end{document}
Rendus obtenus
-
- Administrateur
- Messages : 7977
- Inscription : samedi 28 mai 2005, 14:23
- Statut actuel : Enseignant
Re: [Lualatex] Bases de numération
C'est effectivement bien plus complet que ma proposition initiale. Merci pour le partage !
-
- Utilisateur éprouvé
- Messages : 995
- Inscription : vendredi 12 juin 2009, 22:35
- Statut actuel : Enseignant
- Localisation : Chambéry
Re: [Lualatex] Bases de numération
Moui, enfin pourquoi pas ? Mais lua pour faire une conversion de base, qui est un des algorithmes les plus simples qui soient, c'est pas un peu too much ?
Pour en revenir à TeX, voici l'algorithme minimal ci-dessous (la macro
Pour un truc plus « visuel », on peut aussi faire figurer les divisions successives avec tikzeries (ou sans comme ici) :
Pour en revenir à TeX, voici l'algorithme minimal ci-dessous (la macro
\baseconv
n'est pas purement développable, mais il est facile d'y remédier) :
Code : Tout sélectionner
\documentclass{article}
\makeatletter
\newcount\base@cnt
\newcount\iter@cnt
\newcommand*\baseconv[1][2]{% base 2 par défaut
\def\base@{#1} \iter@cnt\@ne
\baseconv@a
}
\newcommand*\baseconv@a[1]{%
\base@cnt#1 \divide\base@cnt\base@
\expandafter\edef\csname reste@\number\iter@cnt\endcsname{\number\numexpr#1-\base@cnt*\base@}%
\csname @\ifnum\base@cnt>\z@ first\else second\fi oftwo\endcsname
{\advance\iter@cnt\@ne \expandafter\baseconv@a\expandafter{\number\base@cnt}}%
\baseconv@b
}
\newcommand*\baseconv@b{\ensuremath{(\hbox{\baseconv@c\iter@cnt})_{\base@}}}
\newcommand*\baseconv@c[1]{%
\expandafter\display@digit\csname reste@\number#1\endcsname
\ifnum#1>\@ne
\ifnum\base@>16 ;\fi
\expandafter\baseconv@c\expandafter{\number\numexpr#1-1\expandafter}%
\fi
}
\newcommand*\display@digit[1]{%
\ifnum\base@>16
#1%
\else
\ifcase#1
0\or1\or2\or3\or4\or5\or6\or7\or8\or9%
\or A\or B\or C\or D\or E\or F%
\fi
\fi
}
\makeatother
\begin{document}
\parindent0pt
Voici une conversion : $499=\baseconv{499}$
\bigskip
Une autre conversion : $499=\baseconv[3]{499}$
\bigskip
Une autre conversion : $499=\baseconv[16]{499}$
\bigskip
Une autre conversion : $499=\baseconv[20]{499}$
\end{document}
Code : Tout sélectionner
\documentclass{article}
\usepackage{xcolor}
\makeatletter
\newbox\base@cntox
\newcount\base@cnt
\newcount\iter@cnt
\newcommand*\conversion[2][2]{% base 2 par défaut
\def\dividende@{#2}%
\def\base@{#1}%
\iter@cnt\@ne\conversion@{#2}%
}
\newcommand*\conversion@[1]{%
\setbox\base@cntox\hbox{\kern0.5em#1\kern0.5em}%
\base@cnt#1 \divide\base@cnt\base@
\vtop{\expandafter\xdef\csname reste@\number\iter@cnt\endcsname{\number\numexpr#1-\base@cnt*\base@}%
\hbox to\wd\base@cntox{\hfil#1\hfil}%
\vskip3pt\hrule height0pt width\wd\base@cntox\vskip3.4pt
\hbox to\wd\base@cntox{\hfil\textbf{\color{red}\csname reste@\number\iter@cnt\endcsname}\kern0.5em}%
}%
\setbox\base@cntox\hbox{8}\vrule height\ht\base@cntox depth3.5ex
\setbox\base@cntox\hbox{\kern0.5em\ifnum\base@>\base@cnt\relax \base@\else\number\base@cnt\fi\kern0.5em}%
\vtop{\hbox to\wd\base@cntox{\kern0.5em\base@\hfil}%
\vskip3pt\hrule height0.4pt width\wd\base@cntox\vskip3pt
\hbox{\csname @\ifnum\base@cnt>\z@ first\else second\fi oftwo\endcsname
{\global\advance\iter@cnt\@ne
\expandafter\conversion@\expandafter{\number\base@cnt}}%
{\kern0.5em\number\base@cnt}%
}%
}%
}
\newcommand*\afficheresultat{$(\dividende@)_{10}=(\hbox{\afficheresultat@\iter@cnt})_{\base@}$}
\newcommand*\afficheresultat@[1]{%
\expandafter\display@digit\csname reste@\number#1\endcsname
\ifnum#1>\@ne
\ifnum\base@>16 ;\fi
\expandafter\afficheresultat@\expandafter{\number\numexpr#1-1\expandafter}%
\fi
}
\newcommand*\display@digit[1]{%
\ifnum\base@>16
#1%
\else
\ifcase#1\relax
0\or1\or2\or3\or4\or5\or6\or7\or8\or9%
\or A\or B\or C\or D\or E\or F%
\fi
\fi
}
\makeatother
\begin{document}
\parindent0pt
Voici une conversion : \conversion{497}
Et son résultat : \afficheresultat
\bigskip
Une autre conversion : \conversion[3]{497}
Et son résultat : \afficheresultat
\bigskip
Une autre conversion : \conversion[16]{497}
Et son résultat : \afficheresultat
\bigskip
Une autre conversion : \conversion[20]{497}
Et son résultat : \afficheresultat
\end{document}
Programmer en TeX, TeXpérimental
-
- Administrateur
- Messages : 7977
- Inscription : samedi 28 mai 2005, 14:23
- Statut actuel : Enseignant
Re: [Lualatex] Bases de numération
Merci pour le partage de cette solution en TeX. Il existe un paquet pour ce genre de choses ?
-
- Utilisateur chevronné
- Messages : 2200
- Inscription : samedi 29 décembre 2007, 00:58
Re: [Lualatex] Bases de numération
Et tout faire en (La)TeX ?un bon petit a écrit : ↑samedi 26 novembre 2022, 10:01 Moui, enfin pourquoi pas ? Mais lua pour faire une conversion de base, qui est un des algorithmes les plus simples qui soient, c'est pas un peu too much ?

LuaTeX existe donc je n'ai plus envie de m'en priver. Pourquoi utiliser Lua serait-il mal ? Que lui reproches-tu excepté que ce ne soit pas du pur (La)TeX ? Qu'on puisse rejeter Python qui ne fait pas partie de l'écosystème (La)TeX, je le conçois, mais LuaTeX est un élément des distributions (La)TeX.
Maintenant moins je fais de (La)TeX, mieux je me porte. C'est juste une question de compétences...

-
- Utilisateur éprouvé
- Messages : 995
- Inscription : vendredi 12 juin 2009, 22:35
- Statut actuel : Enseignant
- Localisation : Chambéry
Re: [Lualatex] Bases de numération
Tout ? Bonne idée, pourquoi pas ?
Mais ce qui est sûr, c'est que sur un forum LaTeX
- pour faire une boucle et itérer sur des éléments d'une liste, c'est TeX et non pas Python.
- pour faire un algorithme arithmétique récursif élémentaire (genre PGCD, conversion de base) : c'est en TeX et pas besoin de lua, même si lua existe sur le moteur luatex et le format lualatex.
Je suis prêt à parier que vous avez consacré beaucoup plus de temps à vous initier lua, à latex3 ou même python.
C'est vraiment un refus que je ne m'explique pas...
Il va falloir vous habituer à être fatigué dans ce cas.
Sur un forum latex, dégainer un algo en python pour itérer sur une liste, c'est comme si j'allais un forum python ou rust (les 2 langages que je pratique) et que je propose d'itérer sur une liste avec TeX : je me prendrais des remarques. Si je persévérais, elles deviendraient récurrentes (fatigantes si voulez) à juste titre.
Je comprends bien que votre frustration de ne pas savoir programmer en TeX, mais encore une fois, c'est beaucoup moins compliqué que ce que l'on veut croire.
Je ne maitrise pas TeX : je sais comment m'y prendre. Pas plus. Je ne me raconte pas d'histoires.
Ensuite, que TeX ait des défauts, personne ne le nie et surtout pas moi. Est-ce étonnant pour un langage aussi vieux ?
Ce qui est bien, c'est qu'il ne ressemble pas aux autres langages. C'est ça le vrai pied !
Programmer en TeX, TeXpérimental
-
- Utilisateur chevronné
- Messages : 2200
- Inscription : samedi 29 décembre 2007, 00:58
Re: [Lualatex] Bases de numération
Oui, mais je lis en haut de la page "Langage TeX/LaTeX et outils associés".un bon petit a écrit : ↑samedi 26 novembre 2022, 16:55 Mais ce qui est sûr, c'est que sur un forum LaTeX

Frustré ? Non. Juste pragmatique. Je préfère faire mumuse avec d'autres joyeusetés comme Prolog, COQ ou encore Haskell.un bon petit a écrit : ↑samedi 26 novembre 2022, 16:55 Je comprends bien que votre frustration de ne pas savoir programmer en TeX, mais encore une fois, c'est beaucoup moins compliqué que ce que l'on veut croire.
-
- Utilisateur chevronné
- Messages : 1133
- Inscription : jeudi 25 novembre 2010, 22:10
Re: [Lualatex] Bases de numération
Je viens de passer 30 ou 40 minutes sur l'apprentissage de TeX : cela semble très compliqué. L'avantage de Python par exemple, pour reprendre un langage cité auparavant, c'est qu'on peut faire rapidement des choses visibles, ce qui est gratifiant.
On verra bien, mais j'ai du mal à imaginer m'investir sur le langage TeX...
On verra bien, mais j'ai du mal à imaginer m'investir sur le langage TeX...
-
- Administrateur
- Messages : 7977
- Inscription : samedi 28 mai 2005, 14:23
- Statut actuel : Enseignant
Re: [Lualatex] Bases de numération
Contrairement à Python, qui intègre un assez grand nombre de fonctions utiles, Lua et TeX sont deux langages assez légers. On peut d'ailleurs observer que les interpréteurs sont de poids assez similaires.
Par exemple, le passage suivant (voir cette page de la documentation Lua) indique que les développeurs ont fait le choix de ne pas implémenter l'intégralité des fonctionnalités classiques concernant la prise en charge des expressions régulières, afin d'éviter de surcharger le code.
Code : Tout sélectionner
$ du -sh /usr/local/texlive/2022/bin/x86_64-linux/tex /usr/bin/lua
380K /usr/local/texlive/2022/bin/x86_64-linux/tex
304K /usr/bin/lua
Même si tout doit théoriquement pouvoir être fait en TeX, je pense que Lua peut apporter plus de simplicité ou de performance dans la mise en œuvre. Si vous avez des idées d'exemples intéressants, n'hésitez pas à en proposer, car c'est l'objectif de ce sujet.Unlike several other scripting languages, Lua does not use POSIX regular expressions (regexp) for pattern matching. The main reason for this is size: A typical implementation of POSIX regexp takes more than 4,000 lines of code. This is bigger than all Lua standard libraries together. In comparison, the implementation of pattern matching in Lua has less than 500 lines. Of course, the pattern matching in Lua cannot do all that a full POSIX implementation does. Nevertheless, pattern matching in Lua is a powerful tool and includes some features that are difficult to match with standard POSIX implementations.
-
- Utilisateur éprouvé
- Messages : 995
- Inscription : vendredi 12 juin 2009, 22:35
- Statut actuel : Enseignant
- Localisation : Chambéry
Re: [Lualatex] Bases de numération
Grand bien vous fasse, mais avec latex, vous allez vite être coincé en programmation (linéaire ou pas).
Et il est illusoire de croire que lua peut tout. Pour les boites, les alignements, le développement, les commandes robustes/fragiles et toutes autres joyeusetés comme vous dites, il faudra bien passer par latex et tex.
Programmer en TeX, TeXpérimental
-
- Administrateur
- Messages : 7977
- Inscription : samedi 28 mai 2005, 14:23
- Statut actuel : Enseignant
Re: [Lualatex] Bases de numération
L'objectif n'est clairement pas de tout faire en Lua, ni de tout faire en TeX. L'un des intérêts du moteur luatex est justement de pouvoir profiter du meilleur de ces deux langages, qui me semble assez complémentaires. Par exemple, Lua apporte de mon point de vue une certaine plus-value grâce aux fonctionnalités suivantes.
- Tout ce qui concerne le calcul numérique.
- Manipulation de listes.
- Utilisation d'expressions régulières.
-
- Utilisateur chevronné
- Messages : 2200
- Inscription : samedi 29 décembre 2007, 00:58
Re: [Lualatex] Bases de numération
Pour le coup, LaTeX3 a un built-in "clé-en-main".un bon petit a écrit : ↑samedi 26 novembre 2022, 10:01 Moui, enfin pourquoi pas ? Mais lua pour faire une conversion de base, qui est un des algorithmes les plus simples qui soient, c'est pas un peu too much ?
Code : Tout sélectionner
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\foo}{mm}{
$#1 = ( \int_to_base:nn { #1 } { #2 } )\sb{#2}$
}
\ExplSyntaxOff
\begin{document}
\foo{1234567}{2}
\foo{1234567}{3}
\foo{1234567}{4}
\foo{1234567}{5}
\foo{1234567}{10}
\foo{1234567}{16}
\foo{1234567}{36}
\end{document}
-
- Administrateur
- Messages : 7977
- Inscription : samedi 28 mai 2005, 14:23
- Statut actuel : Enseignant
Re: [Lualatex] Bases de numération
Merci, je ne connaissais pas cette fonction. Il faut dire que je ne me suis encore jamais vraiment penché sur LaTeX3. 

-
- Utilisateur chevronné
- Messages : 2200
- Inscription : samedi 29 décembre 2007, 00:58
Re: [Lualatex] Bases de numération
Un bon aperçu est donné dans cette page : https://www.alanshawn.com/latex3-tutorial/.