% -*- coding: utf-8; time-stamp-format: "%02d-%02m-%:y at %02H:%02M:%02S %Z" ; time-stamp-active: nil -*-
%<*dtx>
\def\zeckdtxtimestampaux #1<#2>{#2}
\edef\zeckdtxtimestamp{\zeckdtxtimestampaux Time-stamp: <17-10-2025 at 19:39:13 CEST>}
%</dtx>
%<*drv>
%% ---------------------------------------------------------------
\def\zeckpackdate{2025/10/17}%
\def\zeckversion {0.9c}%
%</drv>
%<*dtx>
\catcode0 0 \catcode`\\ 12
^^@iffalse
%</dtx>
%<*readme>--------------------------------------------------------
| Source:   zeckendorf.dtx
| Version:  0.9c, 2025/10/17
| Author:   Jean-François Burnol
| Keywords: Zeckendorf representation; Knuth Fibonacci multiplication
| License:  LPPL 1.3c

Aim
===

This package extends `\xinteval`'s syntax:
- The four operations are overloaded to do algebra in `Q(phi)`,
  where phi is a variable standing for the golden ratio. 
- Functions are available in this syntax to compute:
  - Fibonacci numbers,
  - Zeckendorf representations of positive integers (as lists
    of indices),
  - Bergman phi-representations of positive elements of `Z[phi]`
    (as lists of exponents).
- The `$` character serves as infix operator computing the Knuth
  Fibonacci multiplication of positive  integers.

The macro interface also provides conversion of integers to 
Zeckendorf words and Bergman phi-ary representations.

The functionalities can be used in three ways:
- as a LaTeX package: `\usepackage{zeckendorf}`,
- as a Plain e-TeX macro file: `\input zeckendorfcore.tex`,
- or interactively on the command line: `etex zeckendorf`. If
  available use rather `rlwrap etex zeckendorf` for a smoother
  experience.

The package is in alpha stage and its user interface may change
in backwards incompatible ways.
Of course, suggestions are most welcome.

Installation
============

Exert `etex zeckendorf.dtx` to extract macro files.  To build the
documentation run `xelatex` on the extracted `zeckendorf-doc.tex`,
or directly on `zeckendorf.dtx`.

The recommended TDS structure is:

    /tex/generic/zeckendorf/zeckendorfcore.tex
    /tex/generic/zeckendorf/zeckendorf.tex
    /tex/generic/zeckendorf/zeckendorf.sty
    /source/generic/zeckendorf/zeckendorf.dtx
    /doc/generic/zeckendorf/zeckendorf-doc.pdf
    /doc/generic/zeckendorf/README.md

License
=======

Copyright © 2025 Jean-François Burnol

| This Work may be distributed and/or modified under the
| conditions of the LaTeX Project Public License 1.3c.
| This version of this license is in

>   <http://www.latex-project.org/lppl/lppl-1-3c.txt>

| and version 1.3 or later is part of all distributions of
| LaTeX version 2005/12/01 or later.

This Work has the LPPL maintenance status "author-maintained".

The Author and Maintainer of this Work is Jean-François Burnol.

This Work consists of the main source file and its derived files

    zeckendorf.dtx,
    zeckendorfcore.tex, zeckendorf.tex, zeckendorf.sty,
    README.md, zeckendorf-doc.tex, zeckendorf-doc.pdf

%</readme>--------------------------------------------------------
%<*!readme>
%% ---------------------------------------------------------------
%% The zeckendorf package: Zeckendorf representation of big integers
%% Copyright (C) 2025 Jean-Francois Burnol
%%
%</!readme>
%<*changes>-------------------------------------------------------
\item[0.9c (2025/10/17)] This adds many new features and has
  some breaking changes due to renamings, not listed here.
  \begin{itemize}
    \item It is not |\xintiieval| but |\xinteval|'s syntax which is
          now extended.
    \item Variables |phi| and |psi| are defined and one can do algebra
          with |+|, |-|, |*|, and |^| on them in $\QQ(\phi)$.
    \item The Bergman $\phi$-representation is added for elements
          of $\ZZ[\phi]$ in particular for integers.
    \item The |$| % $
          character doing the Knuth Fibonacci multiplication
          on positive integers now uses the (more efficient) Arnoux formula.
          The |$$| % $$
          computes out of deference according to the Knuth formula.
    \item The PDF documentation section on the mathematical background has
          been extended and includes bibliographical references.
    \item The interactive interface integrates all novelties.
  \end{itemize}
\item[0.9b (2025/10/07)]\mbox{}\newline
\textbf{Bug fixes:}
  \begin{itemize}
  \item The instructions for interactive use mentioned |1e100| as possible
    input, but the author had forgotten that this syntax is not legitimate in
    |\xintiieval| (for example |1+1e10| crashes immediately).\newline
    \emph{This remark is obsolete as of 0.9c because the interactive mode
          now uses |\xinteval|, not |\xintiieva|.}
  \item The code tries at some locations to be compatible with \xintexprname
    versions earlier than |1.4n|.  But these versions did not load
    \xintbinhexname automatically and the needed |\RequirePackage| or |\input|
    for Plain \TeX{} was lacking from the \zeckname code.
  \end{itemize}
\textbf{Other changes:} In the interactive interface, the input may now start
  with an |\xintiieval| function such as |binomial| whose first letter coincides
  with one of the letter commands without it being needed to for example
  add some |\empty| control sequence first.  On the other hand, it was possible
  to use the full command names, now only their first letters (lower or uppercase)
  are recognized as such.
\item[0.9alpha (2025/10/06)] Initial release.
%</changes>-------------------------------------------------------
%<*drv>-----------------------------------------------------------
%% latex zeckendorf-doc.tex (thrice) && dvipdfmx zeckendorf-doc.dvi
%% to produce zeckendorf-doc.pdf
%%
%% Doing latexmk -pdf zeckendorf-doc.tex is also possible but
%% will produce a bigger file due usage of pdflatex.
%%
\NeedsTeXFormat{LaTeX2e}[2020/02/02]
\ProvidesFile{zeckendorf-doc.tex}%
[\zeckpackdate\space v\zeckversion\space driver file for %
  zeckendorf documentation (JFB)]%
\PassOptionsToClass{a4paper,fontsize=11pt}{scrartcl}
\RequirePackage{iftex}
\chardef\Withdvipdfmx \iftutex0 \else\ifpdf0 \else1 \fi\fi
\chardef\NoSourceCode 0 % replace 0 by 1 for not including source code
\input zeckendorf.dtx
%%% Local Variables:
%%% mode: latex
%%% End:
%</drv>-----------------------------------------------------------
%<*dtx>
^^@fi ^^@catcode`\ 0 \catcode0 12
\def\hiddenifs{\iftutex0 \else\ifpdf0 \else1 \fi\fi}%
\chardef\noetex 0
\ifx\numexpr\undefined \chardef\noetex 1 \fi
\ifnum\noetex=1 \chardef\extractfiles 0 % extract files, then stop
\else
    \ifx\ProvidesFile\undefined
      \chardef\extractfiles 0 % no LaTeX2e; etex, ... on zeckendorf.dtx
    \else % latex/pdflatex on zeckendorf-doc.tex or on zeckendorf.dtx
      \NeedsTeXFormat{LaTeX2e}[2020/02/02]%
      \ProvidesFile{zeckendorf.dtx}[bundle source (\zeckpackdate)]%
      \ifx\Withdvipdfmx\undefined
        % latex run is on zeckendorf.dtx, we will extract all files
        \chardef\extractfiles 1 % 1 = extract and typeset, 2=only typeset
        \chardef\NoSourceCode 0 % 0 = include source code, 1 = do not
        \PassOptionsToClass{a4paper,fontsize=11pt}{scrartcl}%
        \RequirePackage{iftex}\relax
        \chardef\Withdvipdfmx \hiddenifs
      \else % latex run is on zeckendorf-doc.tex,
        \chardef\extractfiles 2 % no extractions
      \fi
    \fi
\fi
\ifnum\extractfiles<2 % we extract files
 \def\MessageDeFin{\newlinechar10 \let\Msg\message
 \Msg{^^J}%
 \Msg{********************************************************************^^J}%
 \Msg{*^^J}%
 \Msg{* To finish the installation you have to move the following^^J}%
 \Msg{* files into a directory searched by TeX:^^J}%
 \Msg{*^^J}%
 \Msg{*\space\space\space\space zeckendorf.sty^^J}%
 \Msg{*\space\space\space\space zeckendorf.tex^^J}%
 \Msg{*\space\space\space\space zeckendorfcore.tex^^J}%
 \Msg{*^^J}%
 \Msg{* Happy TeXing!^^J}%
 \Msg{*^^J}%
 }%
 \ifnum\extractfiles=0 % only extraction
  \expandafter\def\expandafter\MessageDeFin\expandafter{%
  \MessageDeFin
  \Msg{* To produce the documentation run latex thrice on zeckendorf-doc.tex^^J}%
  \Msg{* then dvipdfmx on zeckendorf-doc.dvi.^^J}%
  \Msg{*^^J}%
  \Msg{********************************************************************^^J}%
  }%
 \else %% *latex run on zeckendorf.dtx
  \ifnum\Withdvipdfmx=1 % for dvipdfmx
   \expandafter\def\expandafter\MessageDeFin\expandafter{%
   \MessageDeFin
   \Msg{* Please use dvipdfmx once the LaTeX runs are done, and^^J}%
   \Msg{* consider renaming zeckendorf.pdf to zeckendorf-doc.pdf^^J}%
   \Msg{********************************************************************^^J}%
   }%
  \else % pdflatex, lualatex or xelatex
   \expandafter\def\expandafter\MessageDeFin\expandafter{%
   \MessageDeFin
   \Msg{* Please consider renaming zeckendorf.pdf to zeckendorf-doc.pdf^^J}%
   \Msg{********************************************************************^^J}%
   }%
  \fi
 \fi
 % file extraction
 \begingroup
    \input docstrip.tex
    \askforoverwritefalse
    \generate{\nopreamble\nopostamble
    \file{README.md}{\from{zeckendorf.dtx}{readme}}
    \usepreamble\defaultpreamble
    \usepostamble\defaultpostamble
    \file{zeckendorfchanges.tex}{\from{zeckendorf.dtx}{changes}}
    \file{zeckendorf-doc.tex}{\from{zeckendorf.dtx}{drv}}
    \file{zeckendorfcore.tex}{\from{zeckendorf.dtx}{core}}
    \file{zeckendorf.tex}{\from{zeckendorf.dtx}{interactive}}
    \file{zeckendorf.sty}{\from{zeckendorf.dtx}{sty}}}
 \endgroup
\else % *latex on zeckendorf-doc.tex we skipped extraction
 \ifnum\Withdvipdfmx=1
  \def\MessageDeFin{\newlinechar10 \let\Msg\message
  \Msg{^^J}% too lazy to add the multipls spaces to make a frame
  \Msg{********************************************************************^^J}%
  \Msg{* Please use dvipdfmx once the LaTeX runs are done^^J}%
  \Msg{********************************************************************^^J}%
  }%
 \fi
\fi
\ifnum\extractfiles=0
% direct tex/etex/xetex on zeckendorf.dtx, files now extracted, stop
  \MessageDeFin\expandafter\end
\fi
\ifdefined\MessageDeFin\AtEndDocument{\MessageDeFin}\fi
%-------------------------------------------------------------------------------
\documentclass {scrartcl}
%%% START OF CUSTOM doc.sty LOADING (May 21, 2022)
\usepackage{doc}[=v2]
% As explained above I was formerly using scrdoc hence ltxdoc indirectly.
% Let's emulate here the little I appear to need from ltxdoc.cls and
% srcdoc.cls.
%
\AtBeginDocument{\MakeShortVerb{\|}}
\DeclareFontShape{OT1}{cmtt}{bx}{n}{<-> ssub * cmtt/m/n}{}
\DeclareFontFamily{OMS}{cmtt}{\skewchar\font 48}  % '60
\DeclareFontShape{OMS}{cmtt}{m}{n}{<-> ssub * cmsy/m/n}{}
\DeclareFontShape{OMS}{cmtt}{bx}{n}{<-> ssub * cmsy/b/n}{}
\DeclareFontShape{OT1}{cmss}{m}{it}{<->ssub*cmss/m/sl}{}
\ifnum\NoSourceCode=1
  \OnlyDescription
\fi
\CodelineNumbered
\DisableCrossrefs
% \setcounter{StandardModuleDepth}{1} % we don't use this mechanism currently
\def\cmd#1{\cs{\expandafter\cmd@to@cs\string#1}}
\def\cmd@to@cs#1#2{\char\number`#2\relax}
% This is hyperref compatible (contrarily to using \bslash)
% I need the \detokenize due to usage in implementation part with names
% containing the underscore for example
\DeclareRobustCommand\cs[1]{\texttt{\textbackslash\detokenize{#1}}}
\providecommand\marg[1]{%
  {\ttfamily\char`\{}\meta{#1}{\ttfamily\char`\}}}
\providecommand\oarg[1]{%
  {\ttfamily[}\meta{#1}{\ttfamily]}}
\providecommand\parg[1]{%
  {\ttfamily(}\meta{#1}{\ttfamily)}}

% There is very little we seem to need from the scrdoc extras: page geometry
% is set by geometry package and a4paper option from zeckendorf.tex file.  So it
% seems I only need the hologo loading:
\usepackage{hologo}
\DeclareRobustCommand*{\eTeX}{\hologo{eTeX}}%
%\DeclareRobustCommand*{\LuaTeX}{\hologo{LuaTeX}}%
%
%%% end of ltxdoc+srcdoc emulation.

\ifnum\NoSourceCode=1 \OnlyDescription\fi
\usepackage{ifpdf}
\ifpdf\chardef\Withdvipdfmx 0 \fi
\makeatletter
\ifnum\Withdvipdfmx=1
% I think those are mostly obsolete...
   \@for\@tempa:=hyperref,bookmark,graphicx,xcolor,pict2e\do
            {\PassOptionsToPackage{dvipdfmx}\@tempa}
   %
   \PassOptionsToPackage{dvipdfm}{geometry}
   \PassOptionsToPackage{bookmarks=true}{hyperref}
   \PassOptionsToPackage{dvipdfmx-outline-open}{hyperref}
   %\PassOptionsToPackage{dvipdfmx-outline-open}{bookmark}
   %
   \def\pgfsysdriver{pgfsys-dvipdfm.def}
\else
   \PassOptionsToPackage{bookmarks=true}{hyperref}
\fi
\makeatother

\pagestyle{headings}

\iftutex\else % but newtxtt requires it anyhow
\usepackage[T1]{fontenc}
\fi

\usepackage[hscale=0.66,vscale=0.75]{geometry}

\usepackage{amsmath}
\usepackage{amssymb}% for \blacktriangleright utilisé par titled-frame
\allowdisplaybreaks

% requires newtxtt 1.05 or later
\usepackage[zerostyle=d,scaled=0.95,straightquotes]{newtxtt}
\renewcommand\familydefault\ttdefault
\usepackage[noendash]{mathastext}
\renewcommand\familydefault\sfdefault

% pas le temps d'expliquer pourquoi
\iftutex
  \catcode`⊙\active\def⊙{\ensuremath{\odot}}
\else
  \DeclareUnicodeCharacter{2299}{\ensuremath{\odot}}
\fi

\usepackage{graphicx}

\usepackage[dvipsnames,svgnames]{xcolor}

\definecolor{joli}{RGB}{225,95,0}
\definecolor{JOLI}{RGB}{225,95,0}
\definecolor{BLUE}{RGB}{0,0,255}
%% \definecolor{niceone}{RGB}{38,128,192}% utilisé avant pour urlcolor
%% \colorlet{jfverbcolor}{yellow!5}
\colorlet{shortverbcolor}{magenta}% 1.6 release NavyBlue RoyalPurple
\colorlet{softwrapcolor}{blue}
\colorlet{digitscolor}{olive}% 1.6 {OrangeRed}

% transféré de xint-manual.tex (maintenant dans xint.dtx)
\DeclareFontFamily{U}{MdSymbolC}{}
\DeclareFontShape {U}{MdSymbolC}{m}{n}{<-> MdSymbolC-Regular}{}

\makeatletter
\newbox\cdbx@SoftWrapIcon
\def\cdbx@SetSoftWrapBox{%
    \setbox\cdbx@SoftWrapIcon\hb@xt@\z@
    {\hb@xt@\fontdimen2\font
        {\hss{\color{softwrapcolor}\usefont{U}{MdSymbolC}{m}{n}\char"97}\hss}%
     \hss}%
   }
\makeatother

\usepackage[english]{babel}

\usepackage{hyperref}
\hypersetup{%
%linktoc=all,%
breaklinks=true,%
colorlinks=true,%
urlcolor=Cerulean,% 1.6 ProcessBlue,%SkyBlue
citecolor=[RGB]{120,29,126},% ACM Purple
linkcolor=PineGreen,%
pdfauthor={Jean-François Burnol},%
pdftitle={The Zeckendorf package},%
pdfsubject={Arithmetic with TeX},%
pdfkeywords={Phi-expansion, arithmetic, TeX},%
pdfstartview=FitH,%
pdfpagemode=UseOutlines}
\usepackage{bookmark}

% importé de xint 2021/05/14
\newcommand\RaisedLabel[2][6]{%
\vspace*{-#1\baselineskip}%
\begingroup
  \let\leavevmode\relax\phantomsection
  \label{#2}%
\endgroup
\vspace*{#1\baselineskip}%
}

%---- \verb, and verbatim like `environments'. \MicroFont et \MacroFont
\makeatletter
\def\MicroFont {\ttfamily\cdbx@SetSoftWrapBox\color{shortverbcolor}}
%\def\MicroFont {\ttfamily \color[named]{OrangeRed}\cdbx@SetSoftWrapBox }

% \MacroFont est utilisé par macrocode, mais sa définition est figée dans
% \macro@font au \begin{document}

\def\MacroFont {\ttfamily \baselineskip12pt\relax }

%--- November 4, 2014 making quotes straight. (maintenu pour *)
%
% there is no hook in \macrocode after \dospecials etc. Thus I will need to
% take the risk that some future evolution of doc.sty (or perhaps scrdoc)
% invalidates the following.
%
% Actually, I should not at all rely on the doc class, I should do it all by
% myself.

\def\macrocode{\macro@code
               \frenchspacing \@vobeyspaces
               \makestarlowast % \makequotesstraight (obsolète)
               \xmacro@code }

%--- lower * symbol in text

\def\lowast{\raisebox{-.25\height}{*}}
\catcode`* \active
\def\makestarlowast {\let*\lowast\catcode`\*\active}%
\catcode`* 12

\def\verb #1%
{%
  \relax\leavevmode\null
  \begingroup
   \MicroFont
   \def\@makeletter##1{\catcode`##1=11\relax}%
   % \scantokens will have a result of inserting a space after cs's.
   % hence the need to have the catcodes of things like _ right.
   % I also need < for > for code comments
   % \dospecials at begin document
   % \do\ \do\\\do\{\do\}\do\$\do\&\do\#\do\^\do\_\do\%\do\~\do\|
   \odef\dospecials{\dospecials\do\:\do\<\do\>\do\-\do\+}%
   % naturally won't work in footnotes though.
   % this code is truly not satisfying, but enough for my needs here.
   \catcode`\\ 11 \catcode`## 11
   % I don't do \catcode`\% 11 to avoid surprises in code comments
   % if my |...| has a linebreak
   \def\@jfverb ##1#1{\let\do\@makeletter \dospecials
   % lowering a bit the *
                      \makestarlowast
   %\let\do\do@noligs  \verbatim@nolig@list % not needed here
                      \@vobeyspaces\everyeof{\noexpand}%
                      \expandafter\@@jfverb\scantokens{##1}\relax}%
  \@jfverb
}%

\def\@@jfverb #1{\ifcat\noexpand#1\relax\endgroup\@\else
       \nobreak\hskip0pt plus .5pt % added 2025/10/06 for Zeckendorf
                                   % only .5pt 2025/10/15
       \discretionary{\copy\cdbx@SoftWrapIcon}{}{}%
       #1\expandafter\@@jfverb\fi }

\makeatother


% everbatim environment
% =====================

% October 13-14, 2014
% Verbatim with an \everypar hook, mainly to have background color, followed by
% execution of the contents (not limited by a group-scope)

\makeatletter
\colorlet{everbatimfgcolor}{DarkBlue}
\colorlet{everbatimbgcolor}{Beige}
\colorlet{everbatimxfgcolor}{Maroon}

\def\everbatim {\s@everbatim\@everbatim}
\@namedef{everbatim*}{\s@everbatim\@everbatimx}

% Note: one can not use everbatim inside itself or everbatim* inside itself
\def\s@everbatim {%
     \everbatimtop % put there size changes
       \topsep    \z@skip
       \partopsep \z@skip
       \itemsep   \z@skip
       \parsep    \z@skip
       \parskip   \z@skip
       \lineskip  \z@skip
     \let\do\@makeother \dospecials
     \let\do\do@noligs  \verbatim@nolig@list
     \makestarlowast
     \everbatimhook
     \trivlist
       \@topsepadd \z@skip
       \item\relax
       \leftskip   \@totalleftmargin
       \rightskip  \z@skip
       \parindent  \z@
       \parfillskip\@flushglue
       \parskip    \z@skip
       \@@par
       \def\par{\leavevmode\null\@@par\pagebreak[1]}%
       \everypar\expandafter{\the\everypar \unpenalty
                \everbatimeverypar
                \everypar \expandafter{\the\everypar\everbatimeverypar}%
       }%
       \obeylines \@vobeyspaces
}
% 27 mai 2022, plus de \small
\def\everbatimtop {\MacroFont }%
\let\everbatimhook\empty
\def\everbatimeverypar{\strut
                   {\color{everbatimbgcolor}\vrule\@width\linewidth }%
                   \kern-\linewidth
                   \kern\everbatimindent }
\def\everbatimindent {\z@}% voir plus loin atbegindocument

\begingroup
\lccode`X 13
\catcode`X \active
\lccode`Y `* % this is because of \makestarlowast.
% I have to think whether this is useful: obviously if I were to provide
% everbatim and everbatim*  in a package I wouldn't do that.
\catcode`Y  \active
\catcode`| 0 \catcode`[ 1 \catcode`] 2 \catcode`* 12
\catcode`{ 12 \catcode`} 12 |catcode`\\ 12
|lowercase[|endgroup% both freezes catcodes and converts X to active ^^M
|def|@everbatim #1X#2\end{everbatim}%
  [#2|end[everbatim]|everbatimbottom ]
|def|@everbatimx #1X#2\end{everbatimY}]%
  {#2\end{everbatim*}%
% No group here: this allows executed code to make macro
% definitions which may reused in later uses of everbatim.
% refactored 2022/01/11, rather than passing \newlinechar value
% as was done formerly via everbatim* (see above) and fetching it here as #1 
% it is thus assumed executed contents do not terminate a scope
     \edef\everbatimrestorenewlinechar{\newlinechar\the\newlinechar\relax}%
     \newlinechar 13
% refactored 2022/01/11 to fix a \parskip issue
% attention, \parskip thus set to zero for execution of contents
% reason: avoid extra space if everbatim* is in an \item of a list
% between verbatim and output of execution, if it starts a paragraph
% a \vskip-\parskip approach (cf former \everbatimundoparskip)
% would be no good in case contents create a display
     \edef\everbatimrestoreparskip{\parskip\the\parskip\relax}%
     \parskip\z@skip
% execution of the contents (expected to be LaTeX code...)
     \everbatimxprehook
     \scantokens {#2}%
     \everbatimrestorenewlinechar
     \everbatimrestoreparskip
     \everbatimxposthook
% input after \end{everbatim*} on same line in source is allowed
}%
% L'espace venant du endofline final mis par \scantokens sera inhibé si #2 se
% termine par un % ou un \x, etc...
\let\everbatimbottom\empty

\def\endeverbatim{\if@newlist \leavevmode\fi\endtrivlist}
\@namedef{endeverbatim*}{\endeverbatim}
\def\everbatimxprehook {\colorlet{everbsavedcolor}{.}%
                        \color{everbatimxfgcolor}}%
\def\everbatimxposthook{\color{everbsavedcolor}}
{\sbox0{\color{everbatimxfgcolor}\xdef\@tempa{\current@color}}}
\ifpdf
 \ifluatex
   \edef\everbatimxprehook
       {\pdfextension colorstack\noexpand\@pdfcolorstack push{\@tempa}\relax}
   \def\everbatimxposthook
       {\pdfextension colorstack\@pdfcolorstack pop\relax}
 \else
   \edef\everbatimxprehook
      {\pdfcolorstack\noexpand\@pdfcolorstack push{\@tempa}\relax}
   \def\everbatimxposthook{\pdfcolorstack\@pdfcolorstack pop\relax}
 \fi
\else
  \ifxetex
   \edef\everbatimxprehook{\special{color push \@tempa}}
   \def\everbatimxposthook{\special{color pop}}
  \else
    \ifnum\Withdvipdfmx=1
     \edef\everbatimxprehook{\special{color push \@tempa}}
     \def\everbatimxposthook{\special{color pop}}
    \fi
  \fi
\fi
\makeatother

% 2025/10/05
% Toujours pénible de devoir se battre avec les espaces verticaux de LaTeX.
% J'ai dû réexaminer la situation pour Zeckendorf, différent de bnumexpr
% où j'utilise \[..\] pour les \bneshoweval etc...
\AtBeginDocument{%
% \message{ICI below: \the\belowdisplayskip^^J%
%              belowshort: \the\belowdisplayshortskip^^J%
%              above: \the\abovedisplayskip^^J%
%              aboveshor: \the\abovedisplayshortskip^^J%
% }%
% below: 11.0pt plus 3.0pt minus 6.0pt
% belowshort: 6.5pt plus 3.5pt minus 3.0pt
% above: 11.0pt plus 3.0pt minus 6.0pt
% aboveshort: 0.0pt plus 3.0pt
   \belowdisplayskip\belowdisplayshortskip
   %\abovedisplayskip\belowdisplayskip
}

\usepackage{xspace}

\def\zeckname
   {\href{http://www.ctan.org/pkg/zeckendorf}{zeckendorf}\xspace }%

\def\zecknameimp
   {\texorpdfstring
          {\hyperref[part:zeckendorfcode]{{\color{shortverbcolor}\ttzfamily zeckendorf}}}
          {zeckendorf}%
    \xspace }%

\def\zecknameuserdoc
   {\texorpdfstring
          {\hyperref[titlepage]{{\color{PineGreen}\ttzfamily zeckendorf}}}
          {zeckendorf}%
    \xspace }%

\def\bnumexprname
   {\href{http://www.ctan.org/pkg/bnumexpr}{bnumexpr}\xspace }%
\def\xintkernelname
   {\href{http://www.ctan.org/pkg/xint}{xintkernel}\xspace }%
\def\xintcorename
   {\href{http://www.ctan.org/pkg/xint}{xintcore}\xspace }%
\def\xintname
   {\href{http://www.ctan.org/pkg/xint}{xint}\xspace }%
\def\xinttoolsname
   {\href{http://www.ctan.org/pkg/xint}{xinttools}\xspace }%
\def\xintfracname
   {\href{http://www.ctan.org/pkg/xint}{xintfrac}\xspace }%
\def\xintexprname
   {\href{http://www.ctan.org/pkg/xintexpr}{xintexpr}\xspace }%
\def\xintbinhexname
   {\href{http://www.ctan.org/pkg/xint}{xintbinhex}\xspace }%

\DeclareRobustCommand\ctanpackage[1]{\href{https://ctan.org/pkg/#1}{#1}}

\usepackage{zeckendorf}

\usepackage[nottoc,notlot,notlof,other]{tocbibind}\tocotherhead{subsection}
\usepackage{etoc}
\usepackage{centeredline}
\usepackage[dvipsnames]{xcolor}
\usepackage{colorframed}
\colorlet{TFFrameColor}{teal!20}
\colorlet{TFTitleColor}{purple}
\colorlet{shadecolor}{lightgray!25}

\makeatletter\let\originalcheck@percent\check@percent
             \let\check@percent\relax\makeatother
\usepackage[autolanguage,np]{numprint}
\usepackage{enumitem}

\newenvironment{TeXnote}{\par\footnotesize\medskip\noindent\textbf{\TeX-nical note:
  }}{\par\medskip}

\newcommand\dgts{\textcolor{digitscolor}}
\newcommand\mdgts{\mathcolor{digitscolor}}
\DeclareMathOperator{\ZZ}{\mathbf{Z}}
\DeclareMathOperator{\QQ}{\mathbf{Q}}
\begin{document}
\thispagestyle{empty}
\ttzfamily
\pdfbookmark[1]{Title page}{TOP}

{%
\normalfont\Large\parindent0pt \parfillskip 0pt\relax
 \leftskip 2cm plus 1fil \rightskip 2cm plus 1fil
 The \zeckname package\par
}

\RaisedLabel{titlepage}

{\centering
  \textsc{Jean-François Burnol}\par
  \small
  jfbu (at) free (dot) fr\par
  Package version: \zeckversion\ (\zeckpackdate)\par
  {From source file \texttt{zeckendorf.dtx} of \texttt{\zeckdtxtimestamp}}\par
}


\begin{titled-frame}{Warning}
\small
  This package is still in alpha stage.  Any or all of the user interface may change
  in backwards incompatible ways at each release.

  Suggestions for new features are most welcome!
\end{titled-frame}

\etocsetnexttocdepth{subsubsection}
\etocsettagdepth{code}{section}
\etocsettocstyle{}{}
\etocdefaultlines
\makeatletter
\etocsetstyle{subsubsection}
{\addpenalty\@M\etocfontthree\vspace{\etocsepthree}\noindent
 \etocskipfirstprefix}
%{ -- }% etoc has {\allowbreak\,--\,} but it does not work out well here
{, }% finally doing this.
{\etocname}
{.\hfil\begingroup\baselineskip\etocbaselinespreadthree\baselineskip
 \par\endgroup\addpenalty{-\@highpenalty}}
\makeatother

\tableofcontents

\section{Mathematical background}
\label{sec:math}

Let us recall that the Fibonacci sequence starts with $F_0=0$,
$F_1=1$, and obeys the recurrence $F_n=F_{n-1} + F_{n-2}$ for $n\geq2$.  So $F_2=1$,
$F_3=2$, $F_4=3$ and by a simple induction $F_k = k-1$.  Ahem, not at all!
Here are the first few, starting at $F_2=1$:
\[
\xinteval{*fibseq(2, 18)}\dots
\]
The ratios of consecutive Fibonacci numbers are the convergents of the golden
ratio $\phi$.
\[\phi = \xintDigits:=32;\frac{1+sqrt(5)}2\approx\xintfloateval[-2]{(1+sqrt(5))/2}.\]
The Fibonacci recurrence can also be prolungated to negative $n$'s, and it
turns out that $F_{-n}=(-1)^{n-1}F_n$.

Let us a give a few equations which are constantly in use.  The first one
implies explicitly, in particular, that $\ZZ[\phi]$ (i.e. all polynomial
expression in $\phi$ with integer coefficients) is $\ZZ + \ZZ\phi$.
\begin{equation}
  \label{eq:phik}
  \forall n\in\ZZ\quad \phi^n = F_{n-1} + F_n \phi\,.
\end{equation}
Applying the $\phi\leftrightarrow\psi=-\phi^{-1}=1-\phi$ automorphism of
the ring $\ZZ[\phi]$ and
adding we obtain the \textbf{Lucas} numbers:
\begin{equation}
  \label{eq:lucas}
  L_n = \phi^n + \psi^n = 2 F_{n-1} + F_n = F_{n-1} + F_{n+1}\,.
\end{equation}
If subtracting, we obtain the \textbf{Binet} formula:
\begin{equation}
  \label{eq:binet}
  F_n = \frac{\phi^n - \psi^n}{\phi - \psi}\;.
\end{equation}
Of course one should always keep in mind that $-1<\psi<0$. And perhaps also that
$\phi-\psi=\sqrt5$.

Finally, there is an important formula using $2\times2$-matrices,
closely related with equation \eqref{eq:phik} and the recurrence relation of
the Fibonacci numbers:
\begin{equation}
  \label{eq:matrix}
\forall n\in\ZZ\quad
  \begin{pmatrix}
    1&1\\1&0
  \end{pmatrix}^n =
  \begin{pmatrix}
    F_{n+1}&F_n\\F_n&F_{n-1}
  \end{pmatrix}.
\end{equation}



\def\testN{100000000}
\oodef\testword{\ZeckWord{\testN}}
\oodef\testmaxindex{\ZeckMaxK{\testN}}
\ifnum\xintNthElt{0}{\testword}=\numexpr\testmaxindex-1\relax\else\ERROR\fi

\textbf{Zeckendorf}'s Theorem (\textbf{Lekkerkerker}'s \cite{LEKK}
in 1952 (preprint 1951) attributes the result to
Zeckendorf;  Zeckendorf, who was not in academia, published \cite{ZECK} only
later in 1972)
says that any positive integer has a unique representation as a sum of the
Fibonacci numbers $F_n$, $n\geq2$, under the conditions that no two indices
differ by one, and that no index is repeated.  For example:
\begin{align*}
\xintFor #1 in {10,100,1000,10000}\do{\xdef\tmpcsv{\ZeckIndices{#1}}%
\np{#1} &= {\def\ZeckPrintOne{\ZeckTheFN}\mdgts{\ZeckPrintIndexedSum{\tmpcsv}}} 
           = \mdgts{\ZeckPrintIndexedSum{\tmpcsv}}\\
}
\xintFor #1 in {100000, 1000000, 10000000}\do{\xdef\tmpcsv{\ZeckIndices{#1}}%
\np{#1} &= \def\ZeckPrintOne{\ZeckTheFN}
           \mdgts{\ZeckPrintIndexedSum{\tmpcsv}}\\ &= \mdgts{\ZeckPrintIndexedSum{\tmpcsv}}\\
}
\np{\testN} &= \mdgts{\ZeckPrintIndexedSum{\ZeckIndices{\testN}}}
\end{align*}
This is called the Zeckendorf representation, and it can be given either as
above, or as the list of the indices (in decreasing or increasing order), or
as a binary word which in the examples above are
%
\begin{align*}
\xintFor #1 in {10,100,1000,10000,100000, 1000000, 10000000}\do{
\np{#1} &= \mdgts{\ZeckWord{#1}_{\text{zeck}}}\\
}
\np{\testN} &= \mdgts{\ZeckWord{\testN}_{\text{zeck}}}\\
\np{1000000000} &= \mdgts{\ZeckWord{1000000000}_{\text{zeck}}}
\end{align*}
%
The least significant digit says whether the Zeckendorf representation uses
$F_2$ and so on from right to left (one may prefer to put the binary digits in
the reverse order, but doing as above is more reminiscent of binary, decimal,
or other representations using a given radix).

% In the next-to-last example the word
% length is $\testmaxindex-2+1=\mdgts{\the\numexpr\testmaxindex-1\relax}$, and in
% general it is $K-1$ where $K$ is the largest index such that $F_K$ is at most
% equal to the given positive integer.  For $\np{1000000000}$ this maximal index is
% \dgts{\ZeckMaxK{1000000000}} and indeed the associated word has length
% \dgts{\expanded{\noexpand\xintLength{\ZeckWord{1000000000}}}}.

\ifnum\ZeckMaxK{1000000000}=\numexpr
      \expanded{\noexpand\xintLength{\ZeckWord{1000000000}}}
       +1\relax\else \ERROR\fi

In a Zeckendorf binary word the sub-word
\dgts{11} never occurs, and this, combined wih the fact that
the leading digit is \dgts{1}, characterizes the Zeckendorf words.


\textbf{Donald Knuth} (whose name may ring some bells to \TeX{} users) has
defined in 1988 a \textbf{Fibonacci multiplication} (\cite{KNUTHFIBMUL})
of positive integers via the formula
\begin{equation}\label{eq:kmul}
 a \circ b = \sum_{i,j} F_{a_i+b_j}\,,
\end{equation}
where $a = \sum F_{a_i}$ and $b = \sum F_{b_j}$ are the Zeckendorf
representations of the positive integers $a$ and $b$.  Although it is
sometimes true that formula \eqref{eq:kmul} remains valid when using
non-Zeckendorf expressions of $a$ and/or $b$ as sums of Fibonacci numbers,
this is not a general rule.  The next identity by Knuth, which applies
whenever three positive integers $a$, $b$, $c$ are expressed via their
Zeckendorf representations, is thus non-trivial:
\begin{equation}\label{eq:kassoc}
 (a \circ b) \circ c = \sum_{i,j,k} F_{a_i+b_j+c_k}\,.
\end{equation}
From it, the associativity of the Fibonacci multiplication
follows immediately, the same as
commutativity followed immediately from \eqref{eq:kmul}.

Knuth's proof is combinatorial in nature. \textbf{Pierre Arnoux}
(\cite{ARNOUX}) obtained in 1989 a non-combinatorial proof of associativity
based upon the identification of a certain subset (or subsets) of the ring
$\ZZ[\phi]$, closed under multiplication, and indexed by the positive
integers.  The circle-product on the indices is mapped to the standard
multiplication of these algebraic integers $A_n$: $A_nA_m=A_{n\circ m}$.  As
by-product of this, he obtained the following remarkable alternative formula
for the Knuth product:
\begin{equation}
  \label{eq:arnoux}
  a \circ b = ab + a\sum_j F_{b_j - 1} + b \sum_i F_{a_i - 1}\;.
\end{equation}
Again, here we use the Zeckendorf representations of the positive integers $a$
and $b$. Clearly formula \eqref{eq:arnoux} is advantageous numerically compared
to original definition \eqref{eq:kmul}.  Arnoux also re-interpreted a
``star-product'' which had been defined by \textbf{Horacio Porta} and
\textbf{Kenneth Stolarsky} (\cite{PORTSTOL}).

% If we extend the notion of Zeckendorf representation to all non-negative
% integers by deciding that $0$ is represented by $F_0$ (chosen in preference to
% the empty sum!), then both equations \eqref{eq:kmul} and \eqref{eq:arnoux}
% make $0$ act as the identity.

\textbf{Donald Knuth} (see
\cite[7.1.3]{TAOCP4A}) has shown that any relative integer has a unique
representation as a sum of the ``NegaFibonacci'' numbers $F_{-n}$, $n\geq1$,
again with the condition that no index is repeated and no two indices differ
by one. In the special case of zero, the representation is an empty sum.  Here
is the sequence of these ``NegaFibonacci'' numbers starting at $n=-1$:
% \[
% \xinteval{seq((-1)^(n-1)*fib(n), n=1..16)}\dots
% \]
% implémentation négatifs a marché du premier coup...
% Pas envie pour le moment d'implémenter fibseq(a,b) avec b<=a
\[
\xinteval{*reversed(fibseq(-16,-1))}\dots
\]

% à noter que (-1)^{n-1} au lieu de (-1)^(n-1) donne un résultat très
% contreintuitif car xintexpr va retirer les {..} donc c'est comme
% (-1)^n - 1 donc totalement snas rapport... (si l'input est (-1)^{n-1} * x,
% le 1 sera absorbé par le *x d'ailleurs).

In 1957, the twelve-year-old \textbf{George Bergman} (\cite{BERG})
introduced the notion of
a ``base $\phi$'' number system. This uses
$0$ and $1$ as digits but with the ambiguity rule $011\leftrightarrow100$ due
to $\phi^2=\phi+1$.  He proved that any positive integer can be represented
this way finitely, i.e.\@ is a \emph{finite} sum of powers $\phi^k$, with
decreasing relative integers as exponents (i.e.\@ each power occurring at most
once and it is crucial that negative powers are allowed).  For example:
\[ 100 =
\PhiPrintIndexedSum{\PhiExponents{100}} 
%\phi^9 + \phi^6 + \phi^3 + \phi + \phi^{-4} + \phi^{-7} + \phi^{-10}
=
\def\PhiBasePhiSep{\mathord{,}}\PhiBasePhi{100}_\phi\,.
%1001001010\mathord{,}0001001001_\phi\,.
\]
%
Such a finite ``phi-ary'' representation (it seems ``phi-representation'' is the
more commonly used term in academia) is unique if one adds the condition that
no two exponents differ by one.  This is equivalent to requiring that the
number of terms is minimal.  The real numbers which can be represented by such
finite sums are exactly the positive numbers in $\ZZ[\phi]$, i.e. all
combinations $p + q \phi$ with $p$ and $q$ relative integers which turn out to
be strictly positive.
\[100 - 30\phi = \PhiPrintIndexedSum{\PhiExponents{{100}{-30}}}
=
\def\PhiBasePhiSep{\mathord{,}}\PhiBasePhi{{100}{-30}}_\phi\,.
\]


The naive approach to obtain the finite phi-representations, and actually
prove that they do exist for all positive integers, is to show how to
repeatedly add $1$ (hence also powers of $\phi$). One then only needs to
explain how to subtract $1$ (hence also powers of $\phi$) to deduce
that all $p+q\phi>0$ are representable.  This is actually
what Bergman did.  If one wants, as we do, to be able to obtain the
representations for integers having say more than a few decimal digits, this
theoretical approach is simply not feasible as is, one needs a bit more
thinking.

A theoretical way, called the ``greedy'' algorithm, is based upon the fact
that for any $x = p+q\phi >0$, the maximal exponent $k\in\ZZ$ in its minimal
representation is characterized by $\phi^k\leq x<\phi^{k+1}$.  So one only
needs to get $k$ and then replace $x$ by $x-\phi^k$.  Doing this using
floating point number calculations will only be able to handle integers with
few enough digits to be exactly representable, and may lead at some point to a
negative $x$, hence fail, due to rounding errors.  So here again one has to
think a bit.

This has been done by the author, and the resulting algorithm is implemented
(expandably) here in \eTeX{}.  Of course this is only elementary mathematics
and it would be extremely surprising if the algorithm was not in the
literature.  Inputs of hundreds of digits are successfully handled.  The same,
implemented in C or other language with a library for big integers, would of
course go way beyond and be a thousand times faster.

An ``integer-only'' algorithm (i.e.\@ an algorithm which can be made to
process only integers, but is in fact restricted to them; to compare, the
approach described in the previous paragraph is in principle also
implementable using integers only, but it applies to all $x=p+q\phi>0$ not
only to integers) to obtain the
Bergman minimal $\phi$-representation of a positive integer $N$ is explained
by \textbf{Donald Knuth} in the solution to Problem 35 of section 1.2.8 from
\cite{TAOCP1} (there is a typographical error with a missing negative sign in
an exponent there, on page 495; this has been reported to the author).  It
starts with the position of $N$ with respect to Lucas numbers, the more subtle
case being when $N$ follows an odd indexed Lucas number.  One has to think a
bit how to find efficiently the largest Lucas number at most equal to $N$,
when $N$ has hundreds of digits, which is reducible and equivalent to
identifying the maximal $k$ such as $\phi^k\leq x$, but here $x$ only has to
be an integer $N$. This is very similar to finding the Zeckendorf maximal
index which essentially means to locate $\sqrt{5}N$ with respect to powers of
$\phi$.

For $x=N$ an \textbf{integer} (at least $2$) it can be proven that the smallest
contribution $\phi^{-\ell}$ to the minimal Bergman representation is with
$\ell=k$ if $k$ is even and $\ell=k+1$ is $k$ is odd.  Otherwise stated $\ell$  
is the smallest even integer at least equal to $k$. (So we can always find
the location of the radix separator if we had lost it).

\textbf{Christiane Frougny} and \textbf{Jacques Sakarovitch} (\cite{FROUSAKA})
showed that there exists a (non explicited) finite two-tape automaton which
converts the Zeckendorf expansion of a positive integer into the Bergman
representation (where the part with negative exponents is ``folded'' across
the radix point to sit on top (or below) the part with positive exponents).
Very recently \textbf{Jeffrey Shallit} (\cite{SHAL}) has revisited this topic and
constructed explicitly a Frougny-Sakarovitch automaton.


\iffalse
\begin{equation}
  \label{eq:phipowers}
  \forall n\in\ZZ\quad \phi^n = F_{n-1} + F_n \phi\,,
\end{equation}
observe that the above expression of $100$ is equivalent to the two integer
only relations:
\begin{align*}
  \xinteval{add(fib(n-1), n = 9,6,3,1,-4,-7,-10)}
&=F_8 + F_5 + F_2 + F_0 + F_{-5} + F_{-8} + F_{-11}\,,
\\
   \ZeckNFromIndices{9,6,3,1,-4,-7,-10} 
&= F_9 + F_6 + F_3 + F_1 + F_{-4} + F_{-7} + F_{-10}\,.
\end{align*}
Due to \textbf{Binet}'s formulas, the last relation expresses that $\phi^9 +
\phi^6 + \phi^3 + \phi^1 + \phi^{-4} + \phi^{-7} + \phi^{-10}$ is invariant by
the automorphism $\phi\mapsto -\phi^{-1}=1-\phi$ of $\ZZ[\phi]$. This confirms
that it has to be an integer.
\fi
%\bibliographystyle{unsrt}
%\bibliography{zeckendorf}
\begin{thebibliography}{10}

\bibitem{LEKK}
C.~G. Lekkerkerker.
\newblock Voorstelling van natuurlijke getallen door een som van getallen van
  {F}ibonacci.
\newblock {\em Simon Stevin}, 29:190--195, 1951-1952.

\bibitem{ZECK}
E.~Zeckendorf.
\newblock Repr\'esentation des nombres naturels par une somme de nombres de
  {F}ibonacci ou de nombres de {L}ucas.
\newblock {\em Bull. Soc. Roy. Sci. Li\`ege}, 41:179--182, 1972.

\bibitem{KNUTHFIBMUL}
Donald~E. Knuth.
\newblock Fibonacci multiplication.
\newblock {\em Appl. Math. Lett.}, 1(1):57--60, 1988.

\bibitem{ARNOUX}
Pierre Arnoux.
\newblock Some remarks about {F}ibonacci multiplication.
\newblock {\em Appl. Math. Lett.}, 2(4):319--320, 1989.

\bibitem{PORTSTOL}
H.~Porta and K.~B. Stolarsky.
\newblock The edge of a golden semigroup.
\newblock In {\em Number theory, {V}ol.\ {I} ({B}udapest, 1987)}, volume~51 of
  {\em Colloq. Math. Soc. J\'anos Bolyai}, pages 465--471. North-Holland,
  Amsterdam, 1990.

\bibitem{TAOCP4A}
Donald~E. Knuth.
\newblock {\em The art of computer programming. {V}ol. 4{A}. {C}ombinatorial
  algorithms. {P}art 1}.
\newblock Addison-Wesley, Upper Saddle River, NJ, 2011.

\bibitem{BERG}
George Bergman.
\newblock A number system with an irrational base.
\newblock {\em Math. Mag.}, 31:98--110, 1957/58.

\bibitem{TAOCP1}
Donald~E. Knuth.
\newblock {\em The art of computer programming. {V}ol. 1}.
\newblock Addison-Wesley, Reading, MA, third edition, 1997.
\newblock Fundamental algorithms.

\bibitem{FROUSAKA}
Christiane Frougny and Jacques Sakarovitch.
\newblock Automatic conversion from {F}ibonacci representation to
  representation in base {$\phi$}, and a generalization.
\newblock volume~9, pages 351--384. 1999.
\newblock Dedicated to the memory of Marcel-Paul Sch\"utzenberger.

\bibitem{SHAL}
Jeffrey Shallit.
\newblock Proving properties of {$\varphi$}-representations with the
  \texttt{{W}alnut} theorem-prover.
\newblock {\em Commun. Math.}, 33(2):Paper No. 3, 33, 2025.

\end{thebibliography}

\part{User manual}

\section{Use on the command line}
\label{sec:interactive}

Open a command line window and execute:
\centeredline{|etex zeckendorf|}
then follow the displayed instructions.

The (\TeX{} Live) |*tex| executables are not linked with the |readline|
library, and this makes interactive use quite painful.  If you are on a decent
system, launch the interactive session rather via
\centeredline{|rlwrap etex zeckendorf|}
for a smoother experience. 


\section{The core package features}
\label{sec:macros}

\subsection{Algebra in \texorpdfstring{$\QQ(\phi)$}{Q(phi)}, extensions to the
  \cs{xinteval} syntax}
\label{ssec:xinteval}

The |\xinteval| syntax is extended in the following manner:
\begin{enumerate}
\item Bracketed pairs |[a, b]| represent $a +
  b\phi$, where $\phi$ is the golden ratio, and one can operate on them with
  |+|, |-| (also as prefix unary operator), |*|, |/|, and |^| (or |**|) 
  to do additions, subtractions, multiplications,
  divisions and powers with integer exponents.

  So |a| and |b| can be rational numbers and are not limited to integers for
  these computations.

  |phi| stands for |[0,1]| and its conjugate |psi = [1, -1]| is
  defined also.  One can use on input |a + b phi|, which on output will be
  printed as |[a, b]|.

  \textit{\textbf{DO NOT USE |\phi| OR |\psi|...} except if redefined to expand
  to the letters |phi| and |psi| but this not recommended...}!
\begin{everbatim*}
\xinteval{phi^50, psi^50, phi^50 * psi^50}
\end{everbatim*}
\begin{everbatim*}
\xinteval{(1+phi)(10-7phi)(3+phi)/(2+phi)^3}
\end{everbatim*}
\begin{everbatim*}
\xinteval{add(phi^n, n = -4,-7,-10, 1, 3, 6, 9)}
\end{everbatim*}
\begin{everbatim*}
\xinteval{phi^20 / phi^10}
\end{everbatim*}

  \begin{TeXnote}
    When dividing, and except if both operands are scalars, the coefficients of
    the result are reduced to their smallest terms; but for scalar-only division,
    one needs to use the |reduce()| function explicitly.

    The |[0, 0]| acts as |0| in operations, but is not automatically replaced
    by it, if produced by a subtraction for example. It is not allowed as an
    exponent for powers.
  \end{TeXnote}
\item The functions |phisign()|, |phiabs()|, |phinorm()|, |phiconj()| do what
  one expects.

  \begin{snugshade}
    \textbf{Attention:} |\xinteval| functions are always used with parentheses, not
    with curly braces, contrarily to macros!
  \end{snugshade}

\begin{everbatim*}
\xinteval{phisign(10000 - 6180 phi)}
\end{everbatim*}
\begin{everbatim*}
\xinteval{phisign(10000 - 6181 phi)}
\end{everbatim*}
\begin{everbatim*}
\xinteval{phiabs(10000 - 6181 phi)}
\end{everbatim*}
\begin{everbatim*}
\xinteval{phinorm(10000 - 6180 phi)}
\end{everbatim*}
\begin{everbatim*}
\xinteval{(10000 - 6180 phi) * phiconj(10000 - 6180 phi)}
\end{everbatim*}

\item The function |fib()| computes the Fibonacci numbers (also for negative
  indices), and |fibseq()| will compute a consecutive stretch of
  them. 

\begin{everbatim*}
\xinteval{seq(fib(n), n=-5..5, 10, 20, 100)}
\end{everbatim*}
\begin{everbatim*}
\xinteval{seq(fib(2^n), n=1..7)}
\end{everbatim*}
  \begin{TeXnote}
    In the next example, |\xintFor| expands only once, but |\xinteval| needs
    two expansion steps so we use |\expanded| wrapper.  We could have used
    |\xintFor*| but then we need |\xintCSVtoList| wrapper.  We also could have
    used some |\romannumeral-`0| prefix but I figured |\expanded| looked less
    scary. For details on |\xintFor/\xintFor*| check the \xinttoolsname
    documentation.
  \end{TeXnote}
\begin{everbatim*}
\xintFor #1 in {\expanded{\xinteval{*fibseq(100, 110)}}}%
    \do{#1\xintifForLast{.\par}{,\newline}}
\end{everbatim*}

  In the previous example, note the syntax |*fibseq(100,110)|.  Indeed
  |fibseq()| produces a |nutple| (see \xintexprname documentation), i.e.\@
  the output will display brackets |[...]|:
\begin{everbatim*}
\xinteval{fibseq(20, 25)}
\end{everbatim*}

  With the |*| prefix the brackets are removed.

  \begin{snugshade}
    \textbf{Warning:}
    |fibseq(m,n)| will currently fall in an infinite loop if |n<=m|.
  \end{snugshade}

\item The |zeckindices()| function computes the indices needed for the
  Zeckendorf representation.  The input must be an integer, if its is negative
  it is replaced by its opposite.  The zero input gives an empty output
  (i.e. is printed as |[]|).
\begin{everbatim*}
\xinteval{zeckindices(123456789)}
\end{everbatim*}

We use the |*| prefix to not have brackets in the output.
\begin{everbatim*}
\xinteval{*zeckindices(123456789123456789123456789)}
\end{everbatim*}
\begin{everbatim*}
\xinteval{*zeckindices(1e40)}
\end{everbatim*}

It is easy with this syntax to manipulate the indices in various ways.  Let's
print them from smallest to largest:
\begin{everbatim*}
\xinteval{*reversed(zeckindices(123456789123456789123456789))}
\end{everbatim*}

The power of |\xinteval|, always eager to prove |A=A|, can be demonstrated:
\begin{everbatim*}
\xinteval{add(fib(n), n = *zeckindices(123456789))}
\end{everbatim*}
\begin{everbatim*}
\xinteval{add(fib(n), n = *zeckindices(123456789123456789123456))}
\end{everbatim*}

\item the |$| %$
  is added as infix operator on \emph{positive} integers (it will error if
  used with negative integers), to compute the Knuth Fibonacci multiplication.
  It does it using the Arnoux formula \eqref{eq:kmul}. The |$$| %$$
  does the same but using the original Knuth formula \eqref{eq:kmul}.

  For examples see \autoref{sssec:kmul}.
\item The |phiexponents()| function computes the exponents in the Bergman
  $\phi$-representation of its input.  This input must be either an integer or
  a bracketed pair |[a,b]| or equivalently |a + b phi|, standing for $a+b\phi$
  with $a$ and $b$ relative integers.  It $a + b\phi<0$ it is
  replaced by its opposite.  The output is the empty nutple |[]| if input is
  zero. Non-integer input is truncated to integers.

  The |phiexponents()| function produces a bracketed list.
\begin{everbatim*}
\xinteval{phiexponents(100)}\newline
\xinteval{phiexponents(100  - 50phi)}\newline
\xinteval{phiexponents(-100 + 50phi)}\newline
\xinteval{phiexponents(100  - 50psi)}
\end{everbatim*}

  We can use |*| prefix as already indicated if we prefer not to see the brackets:
\begin{everbatim*}
\xinteval{*phiexponents(3141592653)}
\end{everbatim*}
\end{enumerate}
%
The added |\xinteval| syntax elements are also sometimes examplified alongside
their respective matching macros.  Not all macros defined by the package are
documented, because documentation takes incredible amount of times and induces
costly maintenance.  See the commented source code.

\begin{titled-frame}{Important}
  The added syntax elements are only defined for |\xinteval|.  It is possible
  though to access them inside of |\xintiieval| or |\xintfloateval| using the
  lower-level |\xintexpr|. Here is an example:
\begin{everbatim*}
\xintfloateval{\xintexpr fib(100) / fib(99)\relax}
\end{everbatim*}

  The variables |phi| and |psi| can not be used for operations directly inside
  of |\xintfloateval|.  And they should not be redefined as floating point variables,
  as this would break their usage in |\xinteval|.
%
  But one can transfer computations after having defined first an auxiliary
  |\xintfloateval| function: 
\begin{everbatim*}
\xintdeffloatfunc phi_to_fp(x):= x[0] + (1+sqrt(5))/2 * x[1];
\end{everbatim*}
  Then one can use it this way:
\begin{everbatim*}
\xintfloateval{phi_to_fp(\xintexpr (1+phi)(1+2phi)(1-3phi)\relax)}
\end{everbatim*}
\end{titled-frame}

\subsection{Fibonacci numbers}

\subsubsection{\cs{ZeckTheFN}}

This macro computes Fibonacci numbers.
\begin{everbatim*}
\ZeckTheFN{100}
\end{everbatim*}
\begin{everbatim*}
\ZeckTheFN{100 + 15}
\end{everbatim*}

  As shown, the argument can be an integer expression (only in the sense of
  |\inteval|, not in the one of |\xinteval|, for example you can not have
  powers only additions and multiplications).  Negative arguments are allowed:
\begin{everbatim*}
\ZeckTheFN{0}, \ZeckTheFN{-1}, \ZeckTheFN{-2}, \ZeckTheFN{-3},
\ZeckTheFN{-4} 
\end{everbatim*}

  \begin{titled-frame}{|fib()|}
    The syntax of |\xinteval| is extended via addition of a |fib()| function,
    which gives a convenient interface.  See its documentation in
    \autoref{ssec:xinteval}.
  \end{titled-frame}
\subsubsection{\cs{ZeckTheFSeq}}

This computes not only one but a whole contiguous
  series of Fibonacci numbers but its output format is a sequence of braced
  numbers, and tools such as those of \xinttoolsname are needed to manipulate
  its output.  For this reason it is not further documented here.

  \begin{titled-frame}{|fibseq()|}
    The syntax of |\xinteval| is extended via addition of a |fibseq()|
    function, which gives a convenient interface:
\begin{everbatim*}
\xinteval{fibseq(10,20)}
\end{everbatim*}

\noindent    Notice the square brackets used on output.  In the terminology of
    \xintexprname, the function produces a |nutple|.  Use the |*| prefix to
    remove the brackets:
\begin{everbatim*}
\xinteval{reversed(*fibseq(-20,-10))}
\end{everbatim*}
  \end{titled-frame}

\begin{titled-frame}{IMPORTANT}
  Above we used the |reversed()| function to get the
  output in order from $F_{-10}$ to $F_{-20}$ and not from $F_{-20}$ to
  $F_{-10}$.
  
  \emph{Indeed currently, |fibseq(a,b)| \textbf{falls into an infinite loop
    if $a\geq b$.  Use it only with $a<b$.}}
\end{titled-frame}

\subsection{Zeckendorf representation}


\subsubsection{\cs{ZeckIndices}}

This computes the Zeck representation as a comma
  separated list of indices.  The input is only \emph{f}-expanded, if you need it
  to be an expression you must wrap it in |\xinteval|.

  The macro is also known as |\ZeckZeck|.

\begin{titled-frame}{IMPORTANT}
  The input \textbf{must be positive}.  No check is made that this is the
  case.
\end{titled-frame}

\begin{everbatim*}
\ZeckZeck{123456789123456789123456789}
\end{everbatim*}

\begin{titled-frame}{|zeckindices()|}
  The syntax of |\xinteval| is extended via addition of a |zeckindices()|
  function, which gives a more convenient interface.

  Contrarily to the macro interface, it will silently replace its input
  by its absolue value, and will accept zero as input, and then produce the
  empty nutple.  See examples in \autoref{ssec:xinteval}.
\end{titled-frame}


\subsubsection{\cs{ZeckWord}}

This computes the Zeck representation as a binary word.
  The input is only \emph{f}-expanded, if you need it
  to be an expression you must wrap it in |\xinteval|.

\begin{titled-frame}{IMPORTANT}
  The input \textbf{must be positive}.  No check is made that this is the
  case.
\end{titled-frame}
\begin{everbatim*}
\ZeckWord{123456789}
\end{everbatim*}
\begin{everbatim*}
\ZeckWord{\xinteval{2^40}}
\end{everbatim*}

  As \TeX{} does not by default split long strings of digits at the line ends,
  we gave so far only some small examples.  See \xintname or \bnumexprname
  documentations for a \cs{printnumber} macro able to add linebreaks.  Using 
  such an auxiliary (a bit refined) we can for example obtain this:
\begin{everbatim}
\ZeckWord{\xinteval{2^100}}
\end{everbatim}

\begingroup\colorlet{shortverbcolor}{everbatimxfgcolor}
\expandafter|\expanded{\ZeckWord{\xinteval{2^100}}}|
\endgroup

Compare the above with the list of indices in the Zeckendorf representation:
\textcolor{everbatimxfgcolor}{\ZeckZeck{\xinteval{2^100}}}.

\subsubsection{\cs{ZeckNFromIndices}}

This computes an integer from a list of (comma
  separated) indices.  These indices do not have to be positive, their order
  is indifferent and they can be repeated or differ by only one unit.  The
  list is allowed to be empty. Contiguous commas (or commas separated only by
  space characters) act as a single one, a final comma is tolerated.  A new
  \emph{f}-expansion is done at each item, they can be (\emph{f}-expandable)
  macros.

\begin{everbatim*}
\ZeckNFromIndices{}\newline
\ZeckNFromIndices{100, ,,, 90, 80, 70, 60, 50, 40, 30 , , ,,,}
\end{everbatim*}
\begin{everbatim*}
\ZeckIndices{357128524055170099155}
\end{everbatim*}
\begin{everbatim*}
\ZeckIndices{\ZeckNFromIndices{100, 90, 80, 70, 60, 50, 40, 30}}
\end{everbatim*}
\begin{everbatim*}
\ZeckNFromIndices{3,-1,4,-1,5,-9,2,-6,5,-3}
\end{everbatim*}

  \begin{titled-frame}{Emulation inside \cs{xinteval}}
    There is no associated |\xinteval| function but the functionality is a
    one-liner in its syntax:
\begin{everbatim*}
\xinteval{add(fib(i), i= 100, 90, 80, 70, 60, 50, 40, 30)}
\end{everbatim*}
\begin{everbatim*}
\xinteval{add(fib(i), i= 3, -1, 4, -1, 5, -9, 2, -6, 5, -3)}
\end{everbatim*}

It is even a one-liner to define the function oneself!
\begin{everbatim*}
\xintdeffunc Nfromlist(x):= add(fib(i), i = *x);
\xinteval{Nfromlist([100, 90, 80, 70, 60, 50, 40, 30])}\\
\xinteval{Nfromlist(zeckindices(1e60))}
\end{everbatim*}
  \end{titled-frame}


\subsubsection{\cs{ZeckNfromWord}}

This computes a positive integer from a binary word.
  The word can be arbitrary apart from not being empty.

\begin{everbatim*}
\ZeckNfromWord{1}, \ZeckNfromWord{11}, \ZeckNfromWord{111},
\ZeckNfromWord{1111}, \ZeckNfromWord{11111}
\end{everbatim*}
\begin{everbatim*}
\ZeckNfromWord{\xintReplicate{30}{10}}
\end{everbatim*}
\begin{everbatim*}
\ZeckWord{4052739537880}
\end{everbatim*}


\subsection{Knuth Fibonacci Multiplication}

\subsubsection{\cs{ZeckKMul}, \cs{ZeckAMul}}
\label{sssec:kmul}

Both compute the Knuth multiplication of its two
  \textbf{positive} integer arguments.  The former, using formal
  \eqref{eq:kmul}, the latter using \eqref{eq:arnoux}.
  The two arguments are only
  \emph{f}-expanded, you need to wrap each in an |\xinteval| if
  it is an expression.

\begin{everbatim*}
\ZeckKMul{100}{200}, \ZeckAMul{100}{200}
\end{everbatim*}
\begin{everbatim*}
\ZeckKMul{\ZeckKMul{100}{200}}{300},
\ZeckAMul{\ZeckKMul{100}{200}}{300}
\end{everbatim*}
\begin{everbatim*}
\ZeckKMul{100}{\ZeckKMul{200}{300}},
\ZeckAMul{100}{\ZeckKMul{200}{300}}
\end{everbatim*}

  \begin{titled-frame}{|$|, |$$|}%$$$
    The syntax of |\xinteval| is extended via addition of a |$| %$
    infix operator computing according to the Arnoux formula
    \eqref{eq:arnoux}, and |$$| computing according to the Knuth formula
    \eqref{eq:kmul}.% $$
\begin{everbatim*}
\xinteval{(100 $ 200) $ 300, 100 $ (200 $ 300), 100 $$ 200 $$ 300}
\end{everbatim*}
  \end{titled-frame}

  Let us mention here that we could have
  defined a |knuth()| function easily using the powerful |\xinteval| syntax:%
\begin{everbatim*}
\xintNewFunction{knuth}[2]
   {add(fib(x), x = flat(ndmap(+, *zeckindices(#1); *zeckindices(#2);)))}
\xinteval{knuth(100,200), knuth(knuth(100,200),300),
                          knuth(100,knuth(200,300))}
\end{everbatim*}
\begin{TeXnote}
  We could not have used \expandafter|\string\xintdeffunc| here to define
  |knuth()|, so we used the \expandafter|\string\xintNewFunction| interface.
  The sole inconvenient is that when using |knuth()| it is as if we injected by
  hand the replacement expression, which will have to be parsed by
  \cs{xinteval}.
\end{TeXnote}

The advantage is that we have now the means to check the validity of Knuth's
triple product formula \eqref{eq:kassoc}:
\begin{everbatim*}
\xintNewFunction{knuththree}[3]
 {add(fib(x), x= flat(ndmap(+, *zeckindices(#1);
                               *zeckindices(#2);
                               *zeckindices(#3);)))}
\xinteval{knuththree(100, 200, 300)}
\newline
\xinteval{knuththree(1000, 2000, 3000),
            1000 $ 2000 $ 3000,
            1000 $$ 2000 $$ 3000}
\end{everbatim*}

\subsubsection{\cs{ZeckSetAsKnuthOp}, \cs{ZeckSetAsArnouxOp}}

This takes as input a
  character, or multiple characters, and turns them (as a unit) into an infix
  operator computing the Knuth multiplication, respectively according to the
  original Knuth definition \eqref{eq:kmul} or to the Arnoux formula
  \eqref{eq:arnoux}.  The pre-defined meanings of |$| or |$$| for this will not
  be canceled.  One may use %$
  |\ZeckDeleteOperator|\marg{operator} to delete the existing meaning of an
  |\xinteval| operator.

\begin{titled-frame}{IMPORTANT}
  There is NO WARNING if you override a pre-existing operator from the
  |\xinteval| syntax, and not all such operators are user-documented because
  some exist for internal purposes only.  But if done inside a group or
  environment, the former meaning will be recovered on exit.
\end{titled-frame}

  There are a few important points to be aware of:
  \begin{itemize}[nosep]
  \item You can use a letter such as |o| as operator but it then must be used
    prefixed by |\string| which is not convenient:
\begin{everbatim*}
\ZeckSetAsArnouxOp{o}
\xinteval{100 \string o 200 \string o 300}
\end{everbatim*}
  \item
    With a Unicode engine, they are plenty of available characters
    that are already of catcode 12.  For example:
\begin{everbatim}
\ZeckSetAsArnoux{⊙}
\xinteval{100 ⊙ 200 ⊙ 300}
\end{everbatim}
\begingroup
\iftutex
\catcode`⊙=12
\ZeckSetAsArnouxOp{⊙}
\noindent\textcolor{everbatimxfgcolor}{\xinteval{100 ⊙ 200 ⊙ 300}}
\else
\noindent\textcolor{everbatimxfgcolor}{\xinteval{100 $ 200 $ 300}}
\fi
\endgroup

    You can also use letters from Greek or other scripts, but make
    sure they have catcode 12.


  \item It is not possible to use as operator a control sequence such as
    |\odot|.  It has to be one or more non-letter characters.  It can not be
    the period (full stop) which, although not being a predefined operator is
    recognized as decimal separator (even in |\xinteval| due to some shared
    code with |\xinteval|).

  \item In case your document is compiled with |pdflatex| or |latex| and uses
    Babel, some characters may be catcode active.  To make them part of a name
    of an operator defined by, each such catcode active character has to be
    prefixed with |\string| in the argument of |\ZeckSetAsKnuthOp|.  But
    |\string| is then \emph{unneeded} inside |\xinteval| (since \xintexprname
    |1.4n|).
\end{itemize}


\subsection{Bergman phi-representation}


\subsubsection{\cs{PhiExponents}}

It has a unique mandatory argument which can be (or expand too) either an
integer |a|, or two braced integers |{a}{b}|.

It outputs the comma separated list of the exponents from the minimal Bergman
representation of the absolute value of $a + b \phi$.  If $a + b\phi<0$, this
list will be prefixed by a period.  If $a=b=0$, the output is empty.

\begin{titled-frame}{|phiexponents()|}
  The syntax of |\xinteval| is extended via addition of a |phiexponents()|
  function, which gives a more convenient interface.

  Contrarily to the macro, it loses the information about the sign of the
  input and tacitly replaces it with its absolute value.

  See \autoref{ssec:xinteval} for examples.
\end{titled-frame}
\begin{everbatim*}
\[100\rightarrow \PhiExponents{100}\]
\end{everbatim*}
\begin{everbatim*}
\[100\phi\rightarrow \PhiExponents{{0}{100}}\]
\end{everbatim*}
\begin{everbatim*}
\[1000000\rightarrow \PhiExponents{1000000}\]
\end{everbatim*}
\begin{everbatim*}
$10^{20}\rightarrow{}$ \PhiExponents{\xinteval{10^20}}.
\end{everbatim*}

We did not use math mode for the longer output, because \TeX{} needs extra
instructions to wrap the line.
But the separator can be customized to this aim:
% 0.5pt ne serait pas suffisant
\begin{everbatim*}
\renewcommand\PhiExponentsSep
     {,\allowbreak\hskip0pt plus 1pt\relax}
$10^{50}\rightarrow \PhiExponents{\xinteval{10^50}}$.
\end{everbatim*}

The attentive reader will have noticed though that our math mode does not
differ much from our nice monospace text mode.  Maybe look at some other
\LaTeX{} package
by the author to find some clues explaining this top-quality typesetting.

\subsubsection{\cs{PhiBasePhi}}

It has a unique mandatory argument which can be (or expand two) either an
integer |a|, or two braced integers |{a}{b}|.

It computes the Bergman $\phi$-representation of $x=a+b\phi$ if $x$ turns out
to be positive, outputs $0$ if both $a$ and $b$ vanish, and outputs a minus
sign followed with the expansion of the opposite of $x$ if $x<0$.

The output for positive $x$ is a sequence of $1$'s and $0$'s with possibly a
comma as radix separator (it can be customized, see next).  It either
starts with |1| or with |0,|. It always ends with a |1|.  No |1| is repeated.

  The arguments are \emph{x}-expanded, if you need them
  to be expressions you must wrap them using |\xinteval|.

A little stress-test:
\begin{everbatim*}
\begin{multicols}{2}\def\PhiBasePhiSep{\mathord{,}}
\xintFor* #1 in {\xintSeq[-1]{20}{-21}}\do{%
    $\phi^{#1}=\PhiBasePhi{{\ZeckTheFN{#1-1}}%
                           {\ZeckTheFN{#1}}}_\phi$\par
}
\end{multicols}
\end{everbatim*}

  The radix separator
  is customizable as |\PhiBasePhiSep|.  If using the macro inside math
  mode you will probably want to redefine the default |,| to be |\mathord{,}|.
  \begin{TeXnote}
    It is recommended to use |\RenewDocumentCommand| so that independently
    of the new definition, it will not break in the expansion context
    triggered by |\PhiBasePhi|.
  \end{TeXnote}
\begin{everbatim*}
% or \protected\def if not using LaTeX
\RenewDocumentCommand\PhiBasePhiSep{}{\mathord{\mathcolor{blue}{,}}}
\begin{gather*}
\xintFor #1 in {1, 10,  100, 1000, 10000, 100000, 1000000}\do{%
#1 = \PhiBasePhi{#1}_\phi \xintifForLast{}{\\}}
\end{gather*}
\end{everbatim*}
% Trop d'espace vertical ici, comme d'habitude avec LaTeX
\vspace*{-\baselineskip}
  \begin{titled-frame}{Tip}
    As mentioned elsewhere, \TeX{} and \LaTeX{} will not per default split
    long sequences of zeros and ones at ends of lines.
    See \xintname or \bnumexprname
  documentations for a \cs{printnumber} macro able to add linebreaks.  Using 
  such an auxiliary (a bit refined) we can for example obtain this:
\begin{everbatim}
$10^{50}-10^{50}\phi = {}$\printnumber{%
   \PhiBasePhi{{\xinteval{10^50}}{\xinteval{-10^50}}}}${}_\phi$.
\end{everbatim}

\def\PhiBasePhiSep{,}
\noindent
$10^{50}-10^{50}\phi={}$\expandafter
|\expanded{\PhiBasePhi{{\xinteval{10^50}}{\xinteval{-10^50}}}}|${}_\phi$.

The radix separator is somewhere in the middle.
  \end{titled-frame}

  \begin{TeXnote}
    Maybe this |10^{50}| gives opportunity to stress the following: in
    |\xinteval|, braces |{{...}}| % attention à mon jfverb
    are removed, so for example |2^{10-1}| is same as |2^10-1| and not at all
    |2^(10-1)|.  It is easy to forget this when doing both \TeX{} typesetting
    and |\xinteval| calculations at the same time. By the way, |2^-50| is
    accepted syntax in |\xinteval|, but as here we are using only
    |\xinteval|, negative exponents are a no-go anyhow.
  \end{TeXnote}

\subsubsection{\cs{PhiXfromExponents}}

This computes a $\phi$-integer from an arbitrary list of (comma separated)
exponents, not necessarily ordered.  The output |{a}{b}| is not destined for
direct typesetting, one needs for this to wrap usage of the macro inside of
|\PhiTypesetX|.

The list input is allowed to be empty.  A period upfront the input signals to
change the sign of the output to its opposite.

\begin{TeXnote}
  When using the interactive interface, such a leading period in the list of
  exponents will be produced on output from an |a+b phi| if $a+b\phi<0$, but
  when converting in the other direction, from a list of exponents to some
  |a+b phi|, a leading period will cause the first exponent to be replaced
  with zero, if it is non-negative, and will cause a crash if the first listed
  exponent is negative.
\end{TeXnote}

Contiguous commas (or commas separated only by space characters) act as a
single one, a final comma is tolerated.  A new \emph{f}-expansion is done at
each item, they can be (\emph{f}-expandable) macros.

\begin{everbatim*}
$\PhiTypesetX{\PhiXfromExponents{}}$\newline
$\PhiTypesetX{\PhiXfromExponents{100, 49}}$\newline
$\PhiTypesetX{\PhiXfromExponents{15, 13, 10, 5, 3, 1, -6, -11, -16}}$\\
$\PhiTypesetX{\PhiXfromExponents{.16, 14, 11, 6, 4, 2, -5, -10, -15}}$
\end{everbatim*}

For these next two examples:
\begin{everbatim}
$\PhiTypesetX{\PhiXfromExponents{\PhiExponents{1000}}}$\newline
$\PhiTypesetX{\PhiXfromExponents{\PhiExponents{{1000}{-1000}}}}$
\end{everbatim}
We have to be careful that we previously customized |\PhiExponentsSep| like this:
\begin{everbatim}
\renewcommand\PhiExponentsSep
     {,\allowbreak\hskip0pt plus 1pt\relax}
\end{everbatim}
But this will break |\PhiXfromExponents| because it really needs its argument,
after expansion, to be a genuine comma separated list (possibly with extra
spaces, they do not matter).  So we now reset |\PhiExponentsSep| to its default,
and we can execute successfully the next instructions confirming this package
is excellent at doing nothing:
\begin{everbatim*}
\renewcommand\PhiExponentsSep{, }%
$\PhiTypesetX{\PhiXfromExponents{\PhiExponents{1000}}}$\newline
$\PhiTypesetX{\PhiXfromExponents{\PhiExponents{{1000}{-1000}}}}$
\end{everbatim*}

  \begin{titled-frame}{Emulation inside \cs{xinteval}}
    There is no associated |\xinteval| function but the functionality is a
    one-(or-two)-liner in its syntax:
% même ceci marche
% \xinteval{subs(([add(fib(i-1), i=*L),
%                    add(fib(i), i=*L)]), L=[100, 50, -40, -80])}
\begin{everbatim*}
\xinteval{[add(fib(i-1), i=100, 50, -40, -80),
           add(fib(i),   i=100, 50, -40, -80)]}
\end{everbatim*}

Compare with:
\begin{everbatim*}
$\PhiTypesetX{\PhiXfromExponents{100, 50, -40, -80}}$
\end{everbatim*}

It is even a one-or-two-liner to define a function all by oneself!
\begin{everbatim*}
\xintdeffunc ABfromlist(x):= 
            [add(fib(i-1),i=*x), add(fib(i),i=*x)];
\xinteval{ABfromlist(phiexponents(10^30))}
\end{everbatim*}
  \end{titled-frame}


\subsubsection{\cs{PhiXfromBasePhi}}

This computes an element from $\ZZ[\phi]$ from a Bergman $\phi$-representation.
The input is allowed to be empty. If it contains a comma, that comma must
be preceded by at least one digit.  It is allowed for |1|'s to be consecutive.
A leading minus sign is allowed.

The output |{a}{b}| is not destined for direct typesetting one needs
to wrap it inside of |\PhiTypesetX|.
\begin{everbatim*}
\edef\x{\PhiXfromBasePhi{}, \PhiXfromBasePhi{0}, \PhiXfromBasePhi{-0}}
\meaning\x\newline
$\PhiTypesetX{\PhiXfromBasePhi{10,01}}$\newline
$\PhiTypesetX{\PhiXfromBasePhi{101000100010,001000100001}}$\newline
$\PhiTypesetX{\PhiXfromBasePhi{-101000100010,0010001000011}}$
\end{everbatim*}


\subsection{Typesetting}

\subsubsection{\cs{ZeckPrintIndexedSum}}

This is a typesetting utility which produces (expandably), by default,
   |F_a + F_{a'} +| \dots{} from |a, a', ...|.
\begin{everbatim*}
$\ZeckPrintIndexedSum{\ZeckIndices{10000000000000000000}}$.
\end{everbatim*}

The |+| is injected by |\ZeckPrintIndexedSumSep| whose default definition is:
\begin{everbatim}
\def\ZeckPrintIndexedSumSep{+\allowbreak}
\end{everbatim}
Each index from the input list is given as argument to |\ZeckPrintOne| whose
default definition requires math mode:
\begin{everbatim}
\def\ZeckPrintOne#1{F_{#1}}
\end{everbatim}
If one wants explicit Fibonacci numbers, one can do this:
\begin{everbatim*}
$\def\ZeckPrintOne{\ZeckTheFN}
 \ZeckPrintIndexedSum{\ZeckIndices{10000000000000000000}}$.
\end{everbatim*}

However, as one can see above and was already mentioned, \TeX{} and \LaTeX{}
do not know out-of-the-box to split strings of digits at line endings.  Hence
the first two lines are squeezed, but still overflows, which is not pleasing.

With the help of a \xinttoolsname utility we can redefine |\ZeckPrintOne| to
inject breakpoints in-between consecutive digits:
\begin{everbatim*}
\renewcommand\ZeckPrintOne[1]
   {\xintListWithSep{\allowbreak}{\ZeckTheFN{#1}}}
$\ZeckPrintIndexedSum{\ZeckIndices{10000000000000000000}}$.
\end{everbatim*}

\begingroup
\colorlet{shortverbcolor}{everbatimxfgcolor}
\mathsurround0pt
\def\ZeckPrintIndexedSumSep{{}+{}}
\def\ZeckPrintOne#1{$\expandafter|\expanded{\ZeckTheFN{#1}}|$}%
% exit math mode because we use \ttfamily
   Expert \LaTeX{} users will know how to achieve a result
   such as this one, which pleasantly decorate the linebreaks:

\noindent$\ZeckPrintIndexedSum{\ZeckIndices{10000000000000000000}}$.\par
\endgroup
   
\subsubsection{\cs{PhiPrintIndexedSum}}

It is actually a clone of |\ZeckPrintIndexedSum| which only differs
from it via separate configuration macros:
\begin{everbatim}
\def\PhiPrintIndexedSumSep{+\allowbreak}% same as \ZeckPrintIndexedSumSep
\def\PhiPrintOne#1{\phi^{#1}}% powers of phi rather than Fibonacci
                             % numbers.
\end{everbatim}
As for |\ZeckPrintIndexedSum| the default configuration is thus
math mode only.

\begin{everbatim*}
\[2025 = \PhiPrintIndexedSum{\PhiExponents{2025}}\]
\end{everbatim*}% ah la la
It is important in the above example that |\PhiExponentsSep| has its default
definition because |\PhiPrintIndexedSum| needs to see real commas.

\begin{titled-frame}{TODO?}
  Maybe let it recognize an upfront period (as produced by |\PhiExponents| if
  $x=a+b\phi<0$) in the input, and then use minus signs in the output?
\end{titled-frame}

\subsubsection{\cs{PhiTypesetX}}

This is supposed to receive as (single) argument two braced
relative integers |{a}{b}|.

The default output is math-mode only, as it is of the type $a+b\phi$, with
simplifications for zero or negative coefficients.  This is decided by the
two-arguments macro |\PhiTypesetXPrint| which can be redefined.

For examples, see the documentation of |\PhiXfromExponents| and |\PhiXfromBasePhi|.

\section{Use as a \LaTeX{} package}
\label{sec:latex}

As expected, add to the preamble: \centeredline{|\usepackage{zeckendorf}|}
There are no options.

\section{Use with Plain \eTeX{}}
\label{sec:plain}

You will need to input the core code using:
\centeredline{|\input zeckendorfcore.tex|}

\begin{titled-frame}{IMPORTANT}
  After this |\input|, the catcode regimen is
  a specific one (for example |_|, |:|, and |^| all have catcode letter).  So,
  you will probably want to emit |\ZECKrestorecatcodes| immediately after this
  import, it will reset all modified catcodes to their values as prior to the
  import.
\end{titled-frame}

Then you can use the exact same interface as described in the previous
section.

\section{Changes}
\label{sec:changes}

\begin{description}
\input zeckendorfchanges.tex
\end{description}

\clearpage
\section{License}
\label{sec:license}

\makeatletter
% 2025/10/04
% attention au © qui pose problème avec ts1newtxttz.fd bogué
% j'ai fait le report à MS mais peut-être mon mail il y a plusieurs
% mois a fini dans le spam.  Donc ici ne pas oublier le \ttfamily.
%
% 2025/10/06 le © est cassé avec xelatex + newtxtt. Sur un mwe
% si on utilise newtxtext c'est bon, mais pas ici et je n'ai pas
% le temps de m'acharner.
\def\MacroFont{\ttfamily \baselineskip11pt }%
\begin{verbatim}
Copyright (c) 2025 Jean-François Burnol

| This Work may be distributed and/or modified under the
| conditions of the LaTeX Project Public License 1.3c.
| This version of this license is in

>   <http://www.latex-project.org/lppl/lppl-1-3c.txt>

| and version 1.3 or later is part of all distributions of
| LaTeX version 2005/12/01 or later.

This Work has the LPPL maintenance status "author-maintained".

The Author and Maintainer of this Work is Jean-François Burnol.

This Work consists of the main source file and its derived files

    zeckendorf.dtx,
    zeckendorfcore.tex, zeckendorf.tex, zeckendorf.sty,
    README.md, zeckendorf-doc.tex, zeckendorf-doc.pdf

\end{verbatim}


\StopEventually{\end{document}\endinput}
\makeatletter\let\check@percent\originalcheck@percent\makeatother

% provisoire
\def\csh{\cs}

% workaround
% https://github.com/latex3/latex2e/issues/563
\makeatletter
\AddToHook{env/macrocode/begin}{\partopsep0pt\relax}
\AddToHook{env/macrocode/after}{\@nobreakfalse}
\makeatother
\newgeometry{hscale=0.75,vscale=0.75}% ATTENTION \newgeometry fait
                                % un reset de vscale si on ne le
                                % précise pas ici !!!

\MakePercentIgnore
\AddToHook{env/macrocode/begin}{\bfseries}
%
% \catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11
% \let</dtx>\relax
% \def<*core>{\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 }
%</dtx>
%<*core>
% \etocdepthtag.toc{code}
% \part{Commented source code}
% \localtableofcontents
%
% \label{part:zeckendorfcode}
% \etocmarkbothnouc{\zecknameuserdoc \hyperref[sec:zeckendorfcode]{implementation}}
% \section{Core code}
% \label{sec:code:core}
% \etocignoredepthtags
% \etocsetnexttocdepth{subsubsection}
% \localtableofcontents
%
% A general remark is that expandable macros (usually) \emph{f}-expand their
% arguments, and most are \emph{f}-expandable.  This \emph{f}-expandability is
% achieved via \cs{expanded} triggers, diverging a bit from the overall style
% of the \xintname codebase (which predates availability of \cs{expanded}).
%
% Extracts to |zeckendorfcore.tex|.
%
% \subsection{Loading \xintexprname and setting catcodes}
% |0.9alpha| had a left-over |\noexpand| before the |\endinput| due
% to an oversight after replacing an |\edef| by a |\def|, embarrassing
% but unimportant.  Also it made at a few places some effort to be
% compatible with older \xintname, but did not explicitly require
% \xintbinhexname, which is automatically loaded only since
% \xintexprname |1.4n|.
%    \begin{macrocode}
\input xintexpr.sty
\input xintbinhex.sty
\wlog{Package: zeckendorfcore 2025/10/17 v0.9c (JFB)}%
\edef\ZECKrestorecatcodes{\XINTrestorecatcodes}%
\def\ZECKrestorecatcodesendinput{\ZECKrestorecatcodes\endinput}%
\XINTsetcatcodes%
%    \end{macrocode}
% Small helpers related to \cs{expanded}-based methods.  But the package only
% has a few macros and these helpers are used only once or twice, some macros
% needing their own terminators due to various optimizations in the code
% organization.
%
% |\xintthebareiieval| incorporates a |\romannumeral0| we want the
% once-expanded variant without it for optimization.   And also to avoid
% a |\csname...\endcsname| it uses which was added at
% \xintexprname |1.4o| for Babel reasons, but this is not a public macro
% and I think its internal usages are immune to that, but this is a remark
% in passing and I have
% other things to think about at this time.
%    \begin{macrocode}
\def\zeck_abort#1\xint:{{}}%
\def\zeck_done#1\xint:{\iffalse{\fi}}%
\def\zeckthebareiievalo {%
    \expandafter\xint_stop_atfirstofone\romannumeral0\xintbareiieval
}%
%    \end{macrocode}
% \subsection{Fibonacci numbers}
% \subsubsection{\csh{ZeckTheFN}}
% The multiplicative algorithm is as in the \bnumexprname manual (at
% |1.7b|), but termination is different and simply leaves |F_n;F_{n-1};|
% in input stream (in a form requiring |\xintthe|).  We do not use
% |\csname...\endcsname| branching here, for variety.
%
% |\Zeck@FPair| and |\Zeck@@FPair| are not public interface.
% The former is a wrapper of the latter to handle negative or zero
% argument.
%
% The public |\ZeckTheFN| uses the |\Zeck@FPair| which accepts a negative
% or zero argument.  The non public |\Zeck@@FN| uses |\Zeck@@FPair|
% and is thus limited to positive argument, also it remains in |\xintexpr|
% encapsulated format requiring |\xintthe| for explicit digits.
%
% Macros are constructed to be \emph{f}-expandable.
%    \begin{macrocode}
\def\Zeck@FPair#1{\expandafter\zeck@fpair\the\numexpr #1.}%
\def\zeck@fpair #1{%
   \xint_UDzerominusfork
      #1-\zeck@fpair_n
      0#1\zeck@fpair_n
      0-\zeck@fpair_p
   \krof #1%
}%
\def\zeck@fpair_p #1.{\Zeck@@FPair{#1}}%
\def\zeck@fpair_n #1.{%
    \ifodd#1 \expandafter\zeck@fpair_ei\else\expandafter\zeck@fpair_eii\fi
    \romannumeral`&&@\Zeck@@FPair{1-#1}%
}%
\def\zeck@fpair_ei{\expandafter\zeck@fpair_fi}%
\def\zeck@fpair_eii{\expandafter\zeck@fpair_fii}%
\def\zeck@fpair_fi#1;#2;{%
    \romannumeral0\xintiiexpro #2\expandafter\relax\expandafter;%
    \romannumeral0\xintiiexpro -#1\relax;%
}%
\def\zeck@fpair_fii#1;#2;{%
    \romannumeral0\xintiiexpro -#2\expandafter\relax\expandafter;%
    #1;%
}%
\def\Zeck@@FPair#1{%
    \expandafter\zeck@@fpair@start
    \romannumeral0\xintdectobin{\the\numexpr#1\relax};%
}%
%    \end{macrocode}
% Inlining here at start the |\zeck@@fpair@again| because we don't
% want the |\expandafter|'s here, due to current |\XINTfstop| definition.
%    \begin{macrocode}
\def\zeck@@fpair@start 1#1{%
    \xint_gob_til_sc#1\zeck@@fpair@done;%
    \xint_UDonezerofork
       1#1\zeck@@fpair@zero
        10\zeck@@fpair@one
    \krof
    \XINTfstop\XINTiiexprprint.{{1}};\XINTfstop\XINTiiexprprint.{{0}};%
}%
\def\zeck@@fpair@zero #1;#2;#3{%
    \zeck@@fpair@again#3%
    \romannumeral0\xintiiexpro (#1+2*#2)*#1\expandafter\relax\expandafter;%
    \romannumeral0\xintiiexpro #1*#1+#2*#2\relax;%
}%
\def\zeck@@fpair@one #1;#2;#3{%
    \zeck@@fpair@again#3%
    \romannumeral0\xintiiexpro 2*(#1+#2)*#1+#2*#2\expandafter\relax\expandafter;%
    \romannumeral0\xintiiexpro (#1+2*#2)*#1\relax;%
}%
\def\zeck@@fpair@again#1{%
    \xint_gob_til_sc#1\zeck@@fpair@done;%
    \xint_UDonezerofork
       1#1{\expandafter\zeck@@fpair@zero}%
        10{\expandafter\zeck@@fpair@one}%
    \krof
}%
%    \end{macrocode}
% Srrangely, no |\xint_gob_til_krof|.
%    \begin{macrocode}
\def\zeck@@fpair@done#1\krof{}%
%    \end{macrocode}
% For individual Fibonacci numbers, we have non public |\Zeck@@FN| which
% only works on positive input and has an output needing |\xintthe|.
% We also have non-public |\Zeck@TheFN| and |\Zeck@TheFNminusOne| which
% accept negative input, and whose output is with explicit digits
% (and braced).
%
% The problem with |\xintthe| is that it will trigger the
% |\xintiiexprPrintOne| which is (sadly) user customizable, and also adds
% overhead, we should not use internally.  We define |\zeck@the|.
% Contrarily to |\xintthe| it needs pre-expansion of what comes next,
% and it is important to keep in mind its output is braced.
%    \begin{macrocode}
\def\Zeck@@FN{\expandafter\zeck@@fn\romannumeral`&&@\Zeck@@FPair}%
\def\zeck@@fn#1;#2;{#1}%
\def\zeck@@fnminusone#1;#2;{#2}%
\def\ZeckTheFN{%
    \xintthe\expandafter\zeck@@fn\romannumeral`&&@\Zeck@FPair
}%
\def\zeck@the #1.#2{#2}%
\def\Zeck@TheFN{%
    \expandafter\zeck@the\romannumeral`&&@%
    \expandafter\zeck@@fn\romannumeral`&&@\Zeck@FPair
}%
\def\Zeck@TheFNminusOne{%
    \expandafter\zeck@the\romannumeral`&&@%
    \expandafter\zeck@@fnminusone\romannumeral`&&@\Zeck@FPair
}%
%    \end{macrocode}
% \subsubsection{\csh{ZeckTheFSeq}}
% The computation of stretches of Fibonacci numbers is not needed for the
% package, but is provided for user convenience.  This is lifted from the
% development version of the |\xintname| user manual, which refactored a bit
% the code which has been there for over ten years.
%
% Here we also handle negative arguments but still require the
% second argument to be larger (more positive) than the first.
%    \begin{macrocode}
\def\ZeckTheFSeq#1#2{%#1=starting index, #2>#1=ending index
    \expanded\bgroup\expandafter\ZeckTheF@Seq
    \the\numexpr #1\expandafter.\the\numexpr #2.%
}%
%    \end{macrocode}
% The |#1+1| is because |\Zeck@FPair{N}| expands to |F_{N};F_{N-1};|,
% so here we will have |F_{A+1},F_{A};| as starting point.
% We want up to |F_B|.
% If |B=A+1| there will be nothing to do.
%    \begin{macrocode}
\def\ZeckTheF@Seq #1.#2.{%
    \expandafter\ZeckTheF@Seq@loop
    \the\numexpr #2-#1-1\expandafter.\romannumeral0\Zeck@FPair{#1+1}%
}%
%    \end{macrocode}
% Now leave in stream one coefficient, test if we have reached B
% and until then apply standard Fibonacci recursion.
% We insert |\xintthe| although not needed for typesetting but
% this is useful for matters of defining an associated |fibseq()|
% function.
%
% Edit: actually I insert |\zeck@the| because |\xintthe| expands
% (with lots of overhead due to handling possibility of deeply
% nested leaves) |\xintiiexprPrintOne| which is (regrettably perhaps)
% user customizable and (very theoretically) could cause problems
% if we want to use the |\ZeckTheFSeq| for |fibseq()| support.
%
% This means though that at user level the macro will not obey
% a custom |\xintiiexprPrintOne| (but, |fibseq()| from an |\xinteval|
% will, because this is done by |\xinteval| itself).
%
% MEMO: |\zeck@the| will keep one level of braces.
%    \begin{macrocode}
\def\ZeckTheF@Seq@loop #1.#2;#3;{% standard Fibonacci recursion
    \zeck@the#3\ifnum #1=\z@ \expandafter\ZeckTheF@Seq@end\fi
    \expandafter\ZeckTheF@Seq@loop
    \the\numexpr #1-1\expandafter.%
    \romannumeral0\xintiiexpro #2+#3\relax;#2;%
}%
\def\ZeckTheF@Seq@end#1;#2;{\zeck@the#2\iffalse{\fi}}%
%    \end{macrocode}
% \subsection{Zeckendorf representation}
% \subsubsection{\csh{ZeckNearIndex}, \csh{ZeckMaxK}}
% If the ratio of logarithms was the exact mathematical value it would be
% certain (via rough estimates valid at least for say $x\geq10$, and even
% smaller, but anyhow we can check manually it does work) that its integer
% rounding gives an integer |K| such that either |K| or |K-1| is the largest
% index |J| with $F_J\leq x$.  But the computation is done with only about 8
% or 9 digits of precision.  So certainly this assumption fails for $x$ having
% more than one hundred million decimal digits, and would become a bit risky
% with an input having ten million digits.
%
% But this is way beyond the reasonable range for usage of the package, as
% anyhow \xintname can handle multiplications only with operands of about up
% to \dgts{13000} digits, so there is no worry.
%
% \xintfracname's |\xintiRound{0}| is guaranteed to round correctly the input
% it has been given.  This input is some approximation to an exact theoretical
% value involving ratio of logarithms (and square root of \dgts{5}).  Prior to
% rounding the computed numerical approximation, we are close to the exact
% theoretical value, where ``close'' means we expect to have about \dgts{8}
% leading digits in common (and we have already limited our scope so that we
% are talking about a value less than \dgts{10000} at any rate).  If the
% computed rounding differs from the exact rounding of the exact value it must
% be that argument $x$ is about mid-way (in log scale) between two consecutive
% Fibonacci numbers.  The conclusion is that the integer we obtain after
% rounding can not be anything else than either |J| or |J+1|.
%
% The argument is more subtle than it looks.  The conclusion is important to
% us as it means we do not have to add extraneous checks involving computation
% of one or more additional Fibonacci numbers.
%
% The formula with macros was obtained via an |\xintdeffloatfunc| and
% |\xintverbosetrue| after having set |\xintDigits*| to \dgts{8}, and then we
% optimized a bit manually.  The advantage here is that we don't have to set
% ourself |\xintDigits| and later restore it.
%
% We can not use (except if only caring about interactive sessions where
% we control entirely the whole environment)
% |\XINTinFloatDiv| or |\XINTinFloatMul| if we don't set |\xintDigits| (which
% is user customizable) because they hardcode usage of |\XINTdigits|.
%
% For the exact same reason |0.9b| adds |_raw| postfix which had been
% forgotten at |0.9alpha|.  Indeed |\PoorManLogBaseTen| (without |_raw|) does
% an ``in-float'' conversion of its output, and this uses the current
% |\XINTdigits| and adds unnecessary overhead.  The fix at |0.9b| of this
% |0.9alpha| oversight brought an efficiency gain of about \dgts{5\%} for this
% macro for inputs of \dgts{50} digits.
%    \begin{macrocode}
\def\ZeckNearIndex#1{\xintiRound{0}{%
    \xintFloatDiv[8]{\PoorManLogBaseTen_raw{\xintFloatMul[8]{2236068[-6]}{#1}}}%
                    {20898764[-8]}%
                          }%
}%
%    \end{macrocode}
% Now we compute the actual maximal index.  This macro is only for user
% interface, because when obtaining the Zeckendorf representation via the
% greedy algorithm, we will want for efficienty to not discard the computed
% pair of Fibonacci numbers, but proceed using it.
%    \begin{macrocode}
\def\ZeckMaxK{\expanded\zeckmaxk}%
\def\zeckmaxk#1{\expandafter\zeckmaxk_fork\romannumeral`&&@#1\xint:}%
\def\zeckmaxk_fork#1{%
  \xint_UDzerominusfork
    #1-\zeck_abort
    0#1\zeck_abort
    0-{\zeckmaxk_a#1}%
  \krof
}%
\def\zeckmaxk_a #1\xint:{%
    \expandafter\zeckmaxk_b
    \the\numexpr\ZeckNearIndex{#1}\xint:#1\xint:
}%
\def\zeckmaxk_b #1\xint:{%
    \expandafter\zeckmaxk_c
    \romannumeral`&&@\Zeck@@FPair{#1}#1\xint:
}%
\def\zeckmaxk_c #1;#2;#3\xint:#4\xint:{%
    \expandafter\xintiiifGt\zeck@the#1{#4}%
       {{\expandafter}\the\numexpr#3-1\relax}%
       {{}#3}%
}%
%    \end{macrocode}
% \subsubsection{\csh{ZeckIndices}}
% As explained at start of code comments, I decided when packaging the whole
% thing to make macros \emph{f}-expandable via \cs{expanded}-trigger, not
% \cs{romannumeral}.
%
% This and other macros start by computing the max index.  It then subtracts
% the Fibonacci number from the input and loops.
%    \begin{macrocode}
\def\ZeckIndices{\expanded\zeckindices}%
\let\ZeckZeck\ZeckIndices
\def\zeckindices#1{\expandafter\zeckindices_fork\romannumeral`&&@#1\xint:}%
\def\zeckindices_fork#1{%
  \xint_UDzerominusfork
    #1-\zeck_abort
    0#1\zeck_abort
    0-{\bgroup\zeckindices_a#1}%
  \krof
}%
\def\zeckindices_a #1\xint:{%
    \expandafter\zeckindices_b
    \the\numexpr\ZeckNearIndex{#1}\xint:#1\xint:
}%
\def\zeckindices_b #1\xint:{%
    \expandafter\zeckindices_c
    \romannumeral`&&@\Zeck@@FPair{#1}#1\xint:
}%
\def\zeckindices_c #1;#2;#3\xint:#4\xint:{%
    \expandafter\xintiiifGt\zeck@the#1{#4}\zeckindices_A\zeckindices_B
    #1;#2;#3\xint:#4\xint:
}%
%    \end{macrocode}
% Original version of the code used (here and at some other similar locations)
% |\xinttheiiexpr|.  But the latter uses |\xintiiexprPrintOne| which has been
% documented as user-level customizable.  If a custom |\xintiiexprPrintOne|
% prints |Z| or some other symbol in case of the zero value, our code will
% crash.  And we would like to avoid anyhow the inherent overhead in this
% rather complex mechanism of |\xintiiexprPrintOne| (see \xintexprname source
% code).  We added |\zeck@the| but it still needs one more brace stripping
% step.  Finally we drop using |\xintbareiieval| or |\xintthebareiieval| and do
% the subtraction using |\xintiiSub| for efficiency gain.  We could do it in
% wrong order which would have advantage to not have to grab |#2| in
% |\zeckindices_loop|.  But subtraction has then some overhead for long
% numbers.
%    \begin{macrocode}
\def\zeckindices_A#1;#2;#3\xint:{%
    \the\numexpr#3-1\relax
    \expandafter\zeckindices_loop\zeck@the#2%
}%
\def\zeckindices_B#1;#2;#3\xint:{%
    #3%
    \expandafter\zeckindices_loop\zeck@the#1%
}%
\def\zeckindices_loop #1#2\xint:{%
    \expandafter\zeckindices_loop_i
    \romannumeral0\xintiisub{#2}{#1}\xint:
}%
\def\zeckindices_loop_i#1{%
    \xint_UDzerofork#1\zeck_done 0{, \zeckindices_a#1}\krof
}%
%    \end{macrocode}
% \subsubsection{\csh{ZeckBList}}
% This is the variant which produces the results as a sequence of braced
% indices.  Useful as support for a |zeckindices()| function.
%
% Originally in \xintname, \xinttoolsname, the term ``list'' is used for
% braced items.  In the user manual of this package I have been using ``list''
% more colloquially for comma separated values.  Here I stick with \xintname
% conventions but use |BList| (short for ``list of Braced items'') and not only
% ``List'' in the name.
%    \begin{macrocode}
\def\ZeckBList{\expanded\zeckblist}%
\def\zeckblist#1{\expandafter\zeckblist_fork\romannumeral`&&@#1\xint:}%
\def\zeckblist_fork#1{%
  \xint_UDzerominusfork
    #1-\zeck_abort
    0#1\zeck_abort
    0-{\bgroup\zeckblist_a#1}%
  \krof
}%
\def\zeckblist_a #1\xint:{%
    \expandafter\zeckblist_b
    \the\numexpr\ZeckNearIndex{#1}\xint:#1\xint:
}%
\def\zeckblist_b #1\xint:{%
    \expandafter\zeckblist_c
    \romannumeral`&&@\Zeck@@FPair{#1}#1\xint:
}%
\def\zeckblist_c #1;#2;#3\xint:#4\xint:{%
    \expandafter\xintiiifGt\zeck@the#1{#4}\zeckblist_A\zeckblist_B
    #1;#2;#3\xint:#4\xint:
}%
\def\zeckblist_A#1;#2;#3\xint:{%
    {\the\numexpr#3-1\relax}%
    \expandafter\zeckblist_loop\zeck@the#2%
}%
\def\zeckblist_B#1;#2;#3\xint:{%
    {#3}%
    \expandafter\zeckblist_loop\zeck@the#1%
}%
\def\zeckblist_loop#1#2\xint:{%
    \expandafter\zeckblist_loop_i
    \romannumeral0\xintiisub{#2}{#1}\xint:
}%
\def\zeckblist_loop_i#1{\xint_UDzerofork#1\zeck_done 0{\zeckblist_a#1}\krof}%
%    \end{macrocode}
% \subsubsection{\csh{ZeckWord}}
% This is slightly more complicated than \cs{ZeckIndices} and \cs{ZeckBList}
% because we have to keep track of the previous index to know how many zeros
% to inject.
%    \begin{macrocode}
\def\ZeckWord{\expanded\zeckword}%
\def\zeckword#1{\expandafter\zeckword_fork\romannumeral`&&@#1\xint:}%
\def\zeckword_fork#1{%
  \xint_UDzerominusfork
    #1-\zeck_abort
    0#1\zeck_abort
    0-{\bgroup\zeckword_a#1}%
  \krof
}%
\def\zeckword_a #1\xint:{%
    \expandafter\zeckword_b\the\numexpr\ZeckNearIndex{#1}\xint:
    #1\xint:
}%
\def\zeckword_b #1\xint:{%
    \expandafter\zeckword_c\romannumeral`&&@\Zeck@@FPair{#1}#1\xint:
}%
\def\zeckword_c #1;#2;#3\xint:#4\xint:{%
    \expandafter\xintiiifGt\zeck@the#1{#4}\zeckword_A\zeckword_B
    #1;#2;#3\xint:#4\xint:
}%
\def\zeckword_A#1;#2;#3\xint:#4\xint:{%
    \expandafter\zeckword_d
    \romannumeral0\xintiisub{#4}%
                            {\expandafter\xint_firstofone\zeck@the#2}\xint:
    \the\numexpr#3-1.%
}%
\def\zeckword_B#1;#2;#3\xint:#4\xint:{%
    \expandafter\zeckword_d
    \romannumeral0\xintiisub{#4}%
                            {\expandafter\xint_firstofone\zeck@the#1}\xint:
    #3.%
}%
\def\zeckword_d #1%
    {\xint_UDzerofork#1\zeckword_done0{1\zeckword_e}\krof #1}%
\def\zeckword_done#1\xint:#2.{1\xintReplicate{#2-2}{0}\iffalse{\fi}}%
\def\zeckword_e #1\xint:{%
    \expandafter\zeckword_f\the\numexpr\ZeckNearIndex{#1}\xint:
    #1\xint:
}%
\def\zeckword_f #1\xint:{%
    \expandafter\zeckword_g\romannumeral`&&@\Zeck@@FPair{#1}#1\xint:
}%
\def\zeckword_g #1;#2;#3\xint:#4\xint:{%
    \expandafter\xintiiifGt\zeck@the#1{#4}\zeckword_gA\zeckword_gB
    #1;#2;#3\xint:#4\xint:
}%
\def\zeckword_gA#1;#2;#3\xint:#4\xint:{%
    \expandafter\zeckword_h
    \the\numexpr#3-1\expandafter.%
    \romannumeral0\xintiisub
      {#4}%
      {\expandafter\xint_firstofone\zeck@the#2}%
    \xint:
}%
\def\zeckword_gB#1;#2;#3\xint:#4\xint:{%
    \expandafter\zeckword_h
    \the\numexpr#3\expandafter.%
    \romannumeral0\xintiisub
      {#4}%
      {\expandafter\xint_firstofone\zeck@the#1}%
    \xint:
}%
\def\zeckword_h #1.#2\xint:#3.{%
    \xintReplicate{#3-#1-1}{0}%
    \zeckword_d #2\xint:#1.%
}%
%    \end{macrocode}
% \subsubsection{\csh{ZeckNFromIndices}}
% Spaces before commas are not a problem they disappear in |\numexpr|.
%
% Extraneous commas are skipped, in particular a final comma is allowed.
%
% Each item is \emph{f}-expanded to check not empty, but perhaps we could skip
% expanding, as they end up in |\numexpr|.  Advantage of expansion of each
% item is that at any location we can generate multiple indices if desired.
%    \begin{macrocode}
\def\ZeckNFromIndices{\romannumeral0\zecknfromindices}%
\def\zecknfromindices{\zeck@applyandiisum\Zeck@TheFN}%
\def\zeck@applyandiisum {%
    \expandafter\xintiisum\expanded\zeck@applytocsv
}%
%    \end{macrocode}
% Macro |#1| is supposed to output something within braces.
%    \begin{macrocode}
\def\zeck@applytocsv #1#2{%
    {{\expandafter\zeck@applytocsv_a\expandafter#1%
      \romannumeral`&&@#2,;}}%
}%
\def\zeck@applytocsv_a #1#2{%
    \if;#2\expandafter\zeck@applytocsv_done\fi
    \if,#2\expandafter\zeck@applytocsv_skip\fi
    \zeck@applytocsv_b #1#2%
}%
\def\zeck@applytocsv_b #1#2,{%
    #1{#2}%
    \expandafter\zeck@applytocsv_a\expandafter#1\romannumeral`&&@%
}%
\def\zeck@applytocsv_done#1\zeck@applytocsv_b#2;{}%
\def\zeck@applytocsv_skip #1#2,{%
    \expandafter\zeck@applytocsv_a\expandafter#2\romannumeral`&&@%
}%
%    \end{macrocode}
% \subsubsection{\csh{ZeckNfromWord}}
% The |\xintreversedigits| will \emph{f}-expand its argument.
%    \begin{macrocode}
\def\ZeckNfromWord{\romannumeral0\zecknfromword}%
\def\zecknfromword#1{%
    \expandafter\zecknfromword_a\romannumeral0\xintreversedigits{#1};%
}%
\def\zecknfromword_a{%
    \expandafter\xintiisum\expanded{{\iffalse}}\fi\zecknfromword_b 2.%
}%
\def\zecknfromword_b#1.#2{%
    \if;#2\expandafter\zecknfromword_done\fi
    \if#21{\expandafter\zeck@the\romannumeral`&&@\Zeck@@FN{#1}}\fi
    \expandafter\zecknfromword_b\the\numexpr#1+1.%
}%
\def\zecknfromword_done#1.{\iffalse{{\fi}}}%
%    \end{macrocode}
% \subsection{Bergman representation}
% \subsubsection{\csh{PhiIISign_ab}}
% |\PhiIISign_ab| is for use with two arguments already expanded |{a}{b}|
% and postfixed with |;|, and which are strict integers.
%
% The general macro which accepts both one (unbraced) integer or two (braced)
% integers is defined later for support of the |phisign()| function.
%    \begin{macrocode}
\def\PhiIISign_ab {\romannumeral0\phiiisign_ab}%
\def\phiiisign_ab #1#2;{%
    \xintiiifsgn{#1}%
    {% a < 0
     \xintiiifSgn{#2}%
           {-1}%
           {-1}%
           {% a < 0, b > 0, return 1 iff a^2+ab<b^2
            \xintiiifLt{\xintiiMul{#1}{\xintiiAdd{#1}{#2}}}{\xintiiSqr{#2}}%
            {1}%
            {-1}%
           }%
    }%
    {\xintiiSgn{#2}}%
    {% a > 0
     \xintiiifSgn{#2}%
           {% a > 0, b < 0, return 1 iff a^2+ab>b^2
            \xintiiifGt{\xintiiMul{#1}{\xintiiAdd{#1}{#2}}}{\xintiiSqr{#2}}%
            {1}%
            {-1}%
           }%
           {1}%
           {1}%
    }%
}%
%    \end{macrocode}
% \subsubsection{\cs{PhiMaxE}}
%
% We want the greatest $k$ with $\phi^k \leq  a + b \phi$, assuming
% that the latter is strictly positive.
%
% This macro will not be used directly by |\PhiExponents|, but its helpers
% will.
%
% We need helpers computing with precautions a ratio of logarithms.  The
% explanations about why this strategy works even with inputs having thousands
% of digits (in practice hundreds of digits is reasonable range for using
% \xintname arithmetic) are the same as for the Zeckendorf representation.
%
% These macros need to not make assumptions about |\xintDigits|.  Here is the
% original source as it was used to create the code (not any AI would be able
% to do that... but \xintexprname succeeds!).  In particular note the
% impressive nesting of |\xintiiexpr| inside |\xintfloatexpr|.  The log output
% was then edited by hand to not use macros using tacitly |\XINTdigits|, and
% to reduce to 8 digits of precision as this is enough.
%\begin{verbatim}
%     \xintverbosetrue
%     \xintdeffloatvar Phi := (1 + sqrt(5))/2;
%     \xintdeffloatvar Psi := (1 - sqrt(5))/2;
%     \xintdeffloatvar logPhi := log10(Phi);% would have been precomputed anyhow
%     \xintdefiifunc greedyA(a,b):= \xintfloatexpr
%             round(log10(a+b*Phi) / logPhi)\relax;
%     \xintdefiifunc greedyB(a,b):= \xintfloatexpr
%       round(log10(\xintiiexpr abs(a*(a+b) -sqr(b))\relax/abs(a+b*Psi))
%             / logPhi)\relax;
%\end{verbatim}
%    \begin{macrocode}
\def\bergman_nearindex_A#1;#2;{%
  \xintiRound {0}{%
   \xintFloatDiv[8]{%
    \PoorManLogBaseTen_raw
     {\xintFloatAdd[8]{#1}%
                      {\xintFloatMul[8]{#2}{1618034[-6]}}}%
    }%
    {20898764[-8]}%
  }%
}%
\def\bergman_nearindex_B#1;#2;{%
  \xintiRound {0}{%
   \xintFloatDiv[8]{%
     \PoorManLogBaseTen_raw
     {\xintFloatDiv[8]%
          {\xintiiAbs {\xintiiSub 
                       {\xintiiMul {#1}{\xintiiAdd{#1}{#2}}}%
                       {\xintiiSqr {#2}}}%
          }%
          {\xintAbs {\xintFloatAdd[8]%
                     {#1}{\xintFloatMul[8]{#2}{-618034[-6]}}%
                    }%
          }%
     }%
    }%
    {20898764[-8]}%
  }%
}%
\def\PhiMaxE{\the\numexpr\phimaxe}%
\def\phimaxe #1{%
    \expandafter\phimaxe_a\expanded{{#1}}%
}%
\def\phimaxe_a #1{\expandafter\phimaxe_b\string#1;}%
\catcode`[=1 \catcode`]=2 \catcode`\{=12 % }
\def\phimaxe_b #1[\if#1{\expandafter\phimaxe_X % }
                   \else\expandafter\phimaxe_N\fi #1]%
\catcode`[=12 \catcode`]=12 \catcode`\{=1 % }
\def\phimaxe_N #1;{\phimaxe_ab {#1}{0};}%
\def\phimaxe_X #1{\expandafter\phimaxe_ab\expandafter{\iffalse}\fi}%
\def\PhiMaxE_ab {\romannumeral0\phimaxe_ab}%
\def\phimaxe_ab #1#2;{%
    \expandafter\phimaxe_i\romannumeral`&&@%
    \ifnum\numexpr\xintiiSgn{#1}*\xintiiSgn{#2}\relax=-1
          \expandafter\bergman_nearindex_B
    \else \expandafter\bergman_nearindex_A
    \fi #1;#2;;#1;#2;%
}%
\def\phimaxe_i #1;{%
    \expandafter\phimaxe_j\romannumeral`&&@\zeck@fpair #1.#1;%
}%
\def\phimaxe_j #1;#2;#3;#4;#5;{%
    #3\ifnum
        \expandafter\PhiIISign_ab
           \romannumeral0\zeckthebareiievalo #2-#4\expandafter\relax
           \romannumeral0\zeckthebareiievalo #1-#5\relax ;%
       >0
                 -1\fi\relax
}%
%    \end{macrocode}
% \subsubsection{\csh{PhiBList}}
%
% Will serve (or rather a close derivative) as support for the
% |phiexponents()| function in \cs{xinteval}, and is used both by
% |\PhiExponents| and |\PhiBasePhi|.
%    \begin{macrocode}
\def\PhiBList{\expanded\phiblist}%
\def\phiblist #1{%
    \expandafter\phiblist_a\expanded{{#1}}%
}%
\def\phiblist_a #1{\expandafter\phiblist_b\string#1;}%
\catcode`[=1 \catcode`]=2 \catcode`\{=12 % }
\def\phiblist_b #1[\if#1{\expandafter\phiblist_X % }
                   \else\expandafter\phiblist_N\fi #1]%
\catcode`[=12 \catcode`]=12 \catcode`\{=1 % }
\def\phiblist_N #1;{\phiblist_ab {#1}{0};}%
\def\phiblist_X #1{\expandafter\phiblist_ab\expandafter{\iffalse}\fi}%
\def\PhiBlist_ab {\expanded\phiblist_ab}%
\def\phiblist_ab #1#2;{{%
    \ifcase\PhiIISign_ab{#1}{#2}; %
     0\expandafter\phiblist_stop
    \or
     +\expandafter\phiblist_i
    \else
     -\expandafter\phiblist_neg
    \fi
    #1;#2;%
}}%
\def\phiblist_stop#1;#2;{}%
%    \end{macrocode}
% Attention that adding minus signs here would fool |\xintiiSgn| which make no
% normalization and looks only at first token.
%
% TODO: check if it is more efficient to do |\expanded{\noexpand\foo...}|
% rather than |\expandafter\foo\expanded{...}|.
%    \begin{macrocode}
\def\phiblist_neg#1;#2;{%
    \expandafter\phiblist_i\expanded{\XINT_Opp#1;\XINT_Opp#2;}%
}%
\def\phiblist_i#1;#2;{%
    \expandafter\phiblist_j\romannumeral`&&@%
    \ifnum\numexpr\xintiiSgn{#1}*\xintiiSgn{#2}\relax=-1
          \expandafter\bergman_nearindex_B
    \else \expandafter\bergman_nearindex_A
    \fi #1;#2;;#1;#2;%
}%
\def\phiblist_j #1;{%
    \expandafter\phiblist_k\romannumeral`&&@\zeck@fpair #1.#1;%
}%
\def\phiblist_k #1;#2;#3;#4;#5;{%
    \if1\expandafter\PhiIISign_ab
        \romannumeral0\zeckthebareiievalo #2-#4\expandafter\relax
        \romannumeral0\zeckthebareiievalo #1-#5\relax ;%
      \expandafter\phiblist_ci
    \else
      \expandafter\phiblist_cii
    \fi
    #1;#2;#3;#4;#5;%
}%
%    \end{macrocode}
% The extra level of bracing from |\xintbareiieval|
% is resolved in |\phiblist_again|.
%    \begin{macrocode}
\def\phiblist_ci #1;#2;#3;#4;#5;{%
    {\the\numexpr#3-1\relax}%
    \expandafter\phiblist_again
      \romannumeral0\xintbareiieval #4+#2-#1\expandafter\relax
      \romannumeral0\xintbareiieval #5-#2\relax
}%
\def\phiblist_cii #1;#2;#3;#4;#5;{%
    {#3}%
    \expandafter\phiblist_again
      \romannumeral0\xintbareiieval #4-#2\expandafter\relax
      \romannumeral0\xintbareiieval #5-#1\relax
}%
\def\phiblist_again #1#2{%
    \if0\PhiIISign_ab#1#2;%
        \expandafter\phiblist_stop
    \else
        \expandafter\phiblist_i
    \fi
    #1;#2;%
}%
%    \end{macrocode}
% \subsubsection{\csh{PhiExponents}}
% As this depends upon |\PhiBList| it will have to unbrace
% at each step to check sign of the exponent.
%    \begin{macrocode}
\def\PhiExponents{\expanded\phiexponents}%
\def\phiexponents#1{{%
   \expandafter\phiexponents_a
   \expanded\expandafter\phiblist_a\expanded{{#1}}%
   ;%
}}%
\def\phiexponents_a #1{\if-#1.\fi\phiexponents_b}%
\def\phiexponents_b #1{%
    \if;#1\expandafter\phiexponents_done\fi
    #1\phiexponents_c
}%
\def\phiexponents_c #1{%
    \if;#1\expandafter\phiexponents_done\fi
    \PhiExponentsSep#1\phiexponents_c
}%
\def\phiexponents_done#1\phiexponents_c{}%
\def\PhiExponentsSep{, }%
%    \end{macrocode}
% \subsubsection{\csh{PhiBasePhi}}
% As this depends upon |\PhiBList| it will have to unbrace
% at each step to check sign of the exponent.
%    \begin{macrocode}
\def\PhiBasePhi{\expanded\phibasephi}%
\def\phibasephi#1{{%
   \expandafter\phibasephi_a
   \expanded\expandafter\phiblist_a\expanded{{#1}}%
   ;%
}}%
\def\phibasephi_a #1{%
    \if-#1-\fi
    \if0#1\expandafter\xint_gob_til_sc\fi
    \phibasephi_b
}%
\def\phibasephi_b #1{\phibasephi_c #1.}%
\def\phibasephi_c #1#2.{%
  \if-#1%
     0\PhiBasePhiSep\xintReplicate{#2-1}{0}%
     1\expandafter\phibasephi_n
  \else
     1\expandafter\phibasephi_p
  \fi
  #1#2.%
}%
\def\phibasephi_p #1.#2{\phibasephi_pa #1.#2\xint:}%
\def\phibasephi_pa #1.#2{%
  \if;#2\xintReplicate{#1}{0}\expandafter\xint_gob_til_xint:\fi
  \phibasephi_pb #1.#2%
}%
\def\phibasephi_pb #1.#2#3\xint:{%
  \if-#2%
    \xintReplicate{#1}{0}\PhiBasePhiSep\xintReplicate{#3-1}{0}%
    1\expandafter\phibasephi_n
  \else
    \xintReplicate{#1-#2#3-1}{0}%
    1\expandafter\phibasephi_p
  \fi
  #2#3.%
}%
\def\phibasephi_n #1.#2{\phibasephi_na #1.#2\xint:}%
\def\phibasephi_na #1.#2{%
  \if;#2\expandafter\xint_gob_til_xint:\fi
  \phibasephi_nb #1.#2%
}%
\def\phibasephi_nb #1.#2#3\xint:{%
  \xintReplicate{#1+#3-1}{0}%
  1\phibasephi_n #2#3.%
}%
\def\PhiBasePhiSep{,}%
%    \end{macrocode}
% \subsubsection{\csh{PhiXfromExponents}}
% If the list starts with period, it means it represents
% a negative number (or perhaps zero is there is nothing else).
%    \begin{macrocode}
\def\PhiXfromExponents{\expanded\phixfromexponents}%
\def\phixfromexponents#1{%
    \expandafter\phixfromexponents_a\romannumeral`&&@#1,;%
}%
\def\phixfromexponents_a #1{%
    \if.#1\expandafter\phixfromexponents_n
     \else\expandafter\phixfromexponents_p
    \fi #1%
}%
\def\phixfromexponents_p #1;{{%
    {\xintiiSum{\expanded{\zeck@applytocsv_a\Zeck@TheFNminusOne#1;}}}%
    {\xintiiSum{\expanded{\zeck@applytocsv_a\Zeck@TheFN#1;}}}%
}}%
\def\phixfromexponents_n .#1;{{%
    {\xintiiOpp{\xintiiSum{\expanded{\zeck@applytocsv_a\Zeck@TheFNminusOne#1;}}}}%
    {\xintiiOpp{\xintiiSum{\expanded{\zeck@applytocsv_a\Zeck@TheFN#1;}}}}%
}}%
%    \end{macrocode}
% \subsubsection{\csh{PhiXfromBasePhi}}
% The radix separator must be a comma.  There must be at least one
% digit before the comma, if the latter is there.  Empty input is
% allowed.
% Input must \emph{f}-expand so |\macroA,\macroB| not allowed.
%
% Coded the lazy way by first converting to comma separated list.
% |\phiexponentsfromrep|'s output has a final comma but this is ok.
%    \begin{macrocode}
\def\PhiXfromBasePhi{\expanded\phixfrombasephi}%
\def\phixfrombasephi{\expandafter\phixfromexponents\expanded\phiexponentsfromrep}%
\def\phiexponentsfromrep#1{%
    {{\iffalse}\fi\expandafter\phiexponentsfromrep_a\romannumeral`&&@#1,;\xint:}%
}%
\def\phiexponentsfromrep_a #1{%
    \if-#1.\xint_dothis\phiexponentsfromrep_a\fi
    \if,#1\xint_dothis\zeck_done\fi
    \xint_orthat{\phiexponentsfromrep_b #1}%
}%
\def\phiexponentsfromrep_b #1,#2{%
    \expandafter\phiexponentsfromrep_c\romannumeral0\xintreversedigits{#1};%
    \if;#2\expandafter\zeck_done\else
          \expandafter\phiexponentsfromrep_i\fi #2%
}%
\def\phiexponentsfromrep_c{\phiexponentsfromrep_d 0.}%
\def\phiexponentsfromrep_d#1.#2{%
    \if;#2\expandafter\xint_gob_til_dot\fi
    \if#21#1,\fi
    \expandafter\phiexponentsfromrep_d\the\numexpr#1+1.%
}%
\def\phiexponentsfromrep_i{\phiexponentsfromrep_j -1.}%
\def\phiexponentsfromrep_j#1.#2{%
    \if;#2\expandafter\zeck_done\fi
    \if#21#1,\fi
    \expandafter\phiexponentsfromrep_j\the\numexpr#1-1.%
}%
%    \end{macrocode}
% \subsection{The Knuth Fibonacci multiplication}
% \subsubsection{\csh{ZeckKMul}: Knuth definition}
% Here a |\romannumeral0| trigger is used to match |\xintiisum|.  Although
% it induces defining one more macro we obide by the general coding style of
% \xintname with a CamelCase then a lowercase macro, rather than having them 
% merged as only one.
%    \begin{macrocode}
\def\ZeckKMul{\romannumeral0\zeckkmul}%
\def\zeckkmul#1#2{\expandafter\zeckkmul_a
                  \expanded{\ZeckIndices{#1}%
                            ,;%
                            \ZeckIndices{#2}%
                            ,,}%
}%
%    \end{macrocode}
% The space token at start of |#2| after first one is not a problem
% as it ends up in a |\numexpr| anyhow.
%    \begin{macrocode}
\def\zeckkmul_a{\expandafter\xintiisum\expanded{{\iffalse}}\fi
                \zeckkmul_b}%
\def\zeckkmul_b#1;#2,{%
    \if\relax#2\relax\expandafter\zeckkmul_done\fi
    \zeckkmul_c{#2}#1,\zeckkmul_b#1;%
}%
\def\zeckkmul_c#1#2,{%
    \if\relax#2\relax\expandafter\xint_gobble_iii\fi
    {\expandafter\zeck@the\romannumeral`&&@\Zeck@@FN{#1+#2}}\zeckkmul_c{#1}%
}%
\def\zeckkmul_done#1;{\iffalse{{\fi}}}%
%    \end{macrocode}
% \subsubsection{\csh{ZeckAMul}: Arnoux formula}
% Here a |\romannumeral0| trigger is used to match |\xintiisum|.
%    \begin{macrocode}
\def\ZeckAMul{\romannumeral0\zeckamul}%
\def\zeckamul#1{\expandafter\zeckamul_in\romannumeral`&&@#1;}%
\def\zeckamul_in#1;#2{\expandafter\zeckamul_a\romannumeral`&&@#2;#1;}%
\def\zeckamul_a #1;#2;{\xintiiadd
    {\xintiiMul{#1}{#2}}
    {\xintiiAdd{\xintiiMul{#1}{\ZeckB{#2}}}{\xintiiMul{\ZeckB{#1}}{#2}}}%
}%
%    \end{macrocode}
% \subsubsection{\csh{ZeckB}: B operator}
% Here a |\romannumeral0| trigger is used to match |\xintiisum|.  It is a fact
% of life that |\xintiiSum| needs to grab something at each item before
% expanding it, rather than expanding prior to grabbing.  So we use an
% |\expanded| wrapper.
%    \begin{macrocode}
\def\ZeckB{\romannumeral0\zeckb}%
\def\zeckb#1{\xintiisum{\expanded{\iffalse}\fi
             \expandafter\zeckb_a\expanded\zeckindices{#1},,}}%
%    \end{macrocode}
% |#1-1| is always positive.
%    \begin{macrocode}
\def\zeckb_a#1,{%
    \if\relax#1\relax\expandafter\zeckb_done\fi
    {\expandafter\zeck@the\romannumeral`&&@\Zeck@@FN{#1-1}}\zeckb_a
}%
\def\zeckb_done#1\zeckb_a{\iffalse{\fi}}%
%    \end{macrocode}
% \subsection{Typesetting}
% \subsubsection{\csh{ZeckPrintIndexedSum}}
% Expandable, but needs \emph{x}-expansion.  The default requires math mode,
% at it uses |\sb|. We do not use |_| here due to catcode.  It only
% \emph{f}-expands
% its argument. No repeated or final comma allowed.
%    \begin{macrocode}
\def\ZeckPrintIndexedSumSep{+\allowbreak}%
\def\ZeckPrintOne#1{F\sb{#1}}%
\def\ZeckPrintIndexedSum#1{%
    \expandafter\zeckprintindexedsum\romannumeral`&&@#1,;%
}%
\def\zeckprintindexedsum#1{%
    \if,#1\expandafter\xint_gob_til_sc\fi \zeckprintindexedsum_a#1%
}%
\def\zeckprintindexedsum_a#1,{\ZeckPrintOne{#1}\zeckprintindexedsum_b}%
\def\zeckprintindexedsum_b #1{%
    \if;#1\expandafter\xint_gob_til_sc\fi
    \ZeckPrintIndexedSumSep\zeckprintindexedsum_a#1%
}%
%    \end{macrocode}
% \subsubsection{\csh{PhiPrintIndexedSum}}
% A clone of |\ZeckPrintIndexedSum| with its own namespace.
%    \begin{macrocode}
\let\PhiPrintIndexedSumSep\ZeckPrintIndexedSumSep
\def\PhiPrintOne#1{\phi\sp{#1}}%
\def\PhiPrintIndexedSum#1{%
    \expandafter\phiprintindexedsum\romannumeral`&&@#1,;%
}%
\def\phiprintindexedsum#1{%
    \if,#1\expandafter\xint_gob_til_sc\fi \phiprintindexedsum_a#1%
}%
\def\phiprintindexedsum_a#1,{\PhiPrintOne{#1}\phiprintindexedsum_b}%
\def\phiprintindexedsum_b #1{%
    \if;#1\expandafter\xint_gob_til_sc\fi
    \PhiPrintIndexedSumSep\phiprintindexedsum_a#1%
}%
%    \end{macrocode}
% \subsubsection{\csh{PhiTypesetX}}
%    \begin{macrocode}
\def\PhiTypesetX #1{%
    \expandafter\PhiTypesetXPrint\expanded{#1}%
}%
\def\PhiTypesetXPrint #1#2{%
    \xintiiifSgn{#1}%
      {#1\xintiiifSgn{#2}{#2\phi}{}{+#2\phi}}%
      {\xintiiifSgn{#2}{#2\phi}{0}{#2\phi}}%
      {#1\xintiiifSgn{#2}{#2\phi}{}{+#2\phi}}%
}%
%    \end{macrocode}
% \subsection{Extensions of the \cs{xinteval} syntax}
%
% |fib()| and |fibseq()|  accept negative arguments, but |fibseq(a,b)| must be
% with |b>a|, else falls into an infinite loop.
%
% Initially all was added to |\xintiieval| only, but when it was decided to
% also overload the infix operators with the operations in $\ZZ[\phi]$, it
% felt awkward not to include the division so finally we support $\QQ(\phi)$,
% and had to switch to |\xinteval|.
%
% This has the advantage that the overloading of |-|, |+|, |*| which we do now
% is only fir |\xintexpr|, thus internals of the package which still for
% convenience use |\xintiiexpr| (to compute Fibonacci via the multiplicative
% algorithm) will not get annoying overhead from this overloading of the infix
% operators.
%
% \subsubsection{Provisory ad hoc support for adding \xintexprname operators}
% Unfortunately, contrarily to \bnumexprname, \xintexprname (at
% |1.4o|) has no public interface to define an infix operator, and the macros
% it defines to that end have acquired another meaning at end of loading
% |xintexpr.sty|, so we have to copy quite a few lines of code. This is
% provisory and will be removed when xintexpr.sty will have been udpated. We
% also copy/adapt |\bnumdefinfix|.
%
% We test for existence of |\xintdefinfix| so as to be able to update upstream
% and not have to sync it immediately.  But perhaps upstream will choose some
% other name than |\xintdefinfix|...
%    \begin{macrocode}
\ifdefined\xintdefinfix
  \def\zeckdefinfix{\xintdefinfix {expr}}%
\else
\ifdefined\xint_noxpd\else\let\xint_noxpd\unexpanded\fi % support old xint
\def\ZECK_defbin_c #1#2#3#4#5#6#7#8%
{%
  \XINT_global\def #1##1% \XINT_#8_op_<op>
  {%
    \expanded{\xint_noxpd{#2{##1}}\expandafter}%
    \romannumeral`&&@\expandafter#3\romannumeral`&&@\XINT_expr_getnext
  }%
  \XINT_global\def #2##1##2##3##4% \XINT_#8_exec_<op>
  {%
    \expandafter##2\expandafter##3\expandafter
      {\romannumeral`&&@\XINT:NEhook:f:one:from:two{\romannumeral`&&@#7##1##4}}%
  }%
  \XINT_global\def #3##1% \XINT_#8_check-_<op>
  {%
    \xint_UDsignfork
      ##1{\expandafter#4\romannumeral`&&@#5}%
        -{#4##1}%
    \krof
  }%
  \XINT_global\def #4##1##2% \XINT_#8_checkp_<op>
  {%
    \ifnum ##1>#6%
      \expandafter#4%
      \romannumeral`&&@\csname XINT_#8_op_##2\expandafter\endcsname
    \else
      \expandafter ##1\expandafter ##2%
    \fi
  }%
}%
%    \end{macrocode}
% ATTENTION there is lacking at end here compared to the \bnumexprname version
%           an adjustment for updating minus operator,
%           if some other right precedence than 12, 14, 17 is used.
% Doing this would requiring copying still more, so is not done.
%    \begin{macrocode}
\def\ZECK_defbin_b #1#2#3#4#5%
{%
  \expandafter\ZECK_defbin_c
  \csname XINT_#1_op_#2\expandafter\endcsname
  \csname XINT_#1_exec_#2\expandafter\endcsname
  \csname XINT_#1_check-_#2\expandafter\endcsname
  \csname XINT_#1_checkp_#2\expandafter\endcsname
  \csname XINT_#1_op_-\romannumeral\ifnum#4>12 #4\else12\fi\expandafter\endcsname
  \csname xint_c_\romannumeral#4\endcsname
  #5%
  {#1}% #8 for \ZECK_defbin_c
  \XINT_global
  \expandafter
  \let\csname XINT_expr_precedence_#2\expandafter\endcsname
      \csname xint_c_\romannumeral#3\endcsname
}%
%    \end{macrocode}
% These next two currently lifted from \bnumexprname with some adaptations,
% see previous comment about precedences.
%
% We do not define the extra |\chardef|'s as does \bnumexprname to allow more
% user choices of precedences, not only because nobody will ever use the
% feature, but also because it needs extra configuration for minus unary
% operator.  (as mentioned above)
%    \begin{macrocode}
\def\zeckdefinfix #1#2#3#4%
{%
    \edef\ZECK_tmpa{#1}%
    \edef\ZECK_tmpa{\xint_zapspaces_o\ZECK_tmpa}%
    \edef\ZECK_tmpL{\the\numexpr#3\relax}%
    \edef\ZECK_tmpL
         {\ifnum\ZECK_tmpL<4 4\else\ifnum\ZECK_tmpL<23 \ZECK_tmpL\else 22\fi\fi}%
    \edef\ZECK_tmpR{\the\numexpr#4\relax}%
    \edef\ZECK_tmpR
         {\ifnum\ZECK_tmpR<4 4\else\ifnum\ZECK_tmpR<23 \ZECK_tmpR\else 22\fi\fi}%
    \ZECK_defbin_b {expr}\ZECK_tmpa\ZECK_tmpL\ZECK_tmpR #2%
    \expandafter\ZECK_dotheitselves\ZECK_tmpa\relax
  \unless\ifcsname  
    XINT_expr_exec_-\romannumeral\ifnum\ZECK_tmpR>12 \ZECK_tmpR\else 12\fi
  \endcsname
    \xintMessage{zeckendorf}{Error}{Right precedence not among accepted values.}%
    \errhelp{Accepted values include 12, 14, and 17.}%
    \errmessage{Sorry, you can not use \ZECK_tmpR\space as right precedence.}%
  \fi
  \ifxintverbose
    \xintMessage{zeckendorf}{info}{infix operator \ZECK_tmpa\space
    \ifxintglobaldefs globally \fi
        does
        \xint_noxpd{#2}\MessageBreak with precedences \ZECK_tmpL, \ZECK_tmpR;}%
  \fi
}%
\def\ZECK_dotheitselves#1#2%
{%
    \if#2\relax\expandafter\xint_gobble_ii
    \else
  \XINT_global
      \expandafter\edef\csname XINT_expr_itself_#1#2\endcsname{#1#2}%
      \unless\ifcsname XINT_expr_precedence_#1\endcsname
  \XINT_global
        \expandafter\edef\csname XINT_expr_precedence_#1\endcsname
                        {\csname XINT_expr_precedence_\ZECK_tmpa\endcsname}%
  \XINT_global
        \expandafter\odef\csname XINT_expr_op_#1\endcsname
                        {\csname XINT_expr_op_\ZECK_tmpa\endcsname}%
      \fi
    \fi
    \ZECK_dotheitselves{#1#2}%
}%
%    \end{macrocode}
% There is no ``undefine operator'' in \bnumexprname currently.  Experimental,
% I don't want to spend too much time. I sense there is a potential problem
% with multi-character operators related to ``undoing the itselves'', because
% of the mechanism which allows to use for example |;;| as short-cut for |;;;|
% if |;;| was not pre-defined when |;;;| got defined.  To undefine |;;|, I
% would need to check if it really has been aliased to |;;;|, and I don't do
% the effort here.
%    \begin{macrocode}
\def\ZECK_undefbin_b #1#2%
{%
  \XINT_global\expandafter\let
    \csname XINT_#1_op_#2\endcsname\xint_undefined
  \XINT_global\expandafter\let
    \csname XINT_#1_exec_#2\endcsname\xint_undefined
  \XINT_global\expandafter\let
    \csname XINT_#1_check-_#2\endcsname\xint_undefined
  \XINT_global\expandafter\let
    \csname XINT_#1_checkp_#2\endcsname\xint_undefined
  \XINT_global\expandafter\let
    \csname XINT_expr_precedence_#2\endcsname\xint_undefined
  \XINT_global\expandafter\let
    \csname XINT_expr_itself_#2\endcsname\xint_undefined
}%
\def\zeckundefinfix #1%
{%
    \edef\ZECK_tmpa{#1}%
    \edef\ZECK_tmpa{\xint_zapspaces_o\ZECK_tmpa}%
    \ZECK_undefbin_b {expr}\ZECK_tmpa
%%  \ifxintverbose
    \xintMessage{zeckendorf}{Warning}{infix operator \ZECK_tmpa\space
        has been DELETED!}%
%%  \fi
}%
\fi
\def\ZeckDeleteOperator#1{\zeckundefinfix{#1}}%
%    \end{macrocode}
% Attention, this is like |\bnumdefinfix| and thus does not have same order
% of arguments as the |\ZECK_defbin_b| above.
%    \begin{macrocode}
\def\ZeckSetAsKnuthOp#1{\zeckdefinfix{#1}{\ZeckKMul}{14}{14}}%
\def\ZeckSetAsArnouxOp#1{\zeckdefinfix{#1}{\ZeckAMul}{14}{14}}%
%    \end{macrocode}
% \subsubsection{The \textdollar{} and \textdollar{}\textdollar{} as
% infix operator for the Knuth multiplication}
%    \begin{macrocode}
\ZeckSetAsArnouxOp{$}% $ (<-only to tame Emacs/AUCTeX highlighting)
\ZeckSetAsKnuthOp{$$}% $$
%    \end{macrocode}
%^^A pourquoi espace disparaît après le {**}? D'où le {}.
%^^A mark-up copié collé depuis xintexpr
% \subsubsection{Support macros for \texorpdfstring{$\QQ(\phi)$}{Q(phi)} algebra}
% \paragraph{\csh{PhiSgn}}\mbox{}
%    \begin{macrocode}
\def\PhiSign{\romannumeral0\phisign}%
\def\phisign #1{%
    \expandafter\phisign_a\expanded{{#1}}%
}%
\def\phisign_a #1{\expandafter\phisign_b\string#1;}%
\catcode`[=1 \catcode`]=2 \catcode`\{=12 % }
\def\phisign_b #1[\if#1{\expandafter\phisign_X % }
                   \else\expandafter\phisign_N\fi #1]%
\catcode`[=12 \catcode`]=12 \catcode`\{=1 % }
\def\phisign_N #1;{\XINT_sgn #1\xint:}%
\def\phisign_X #1{\expandafter\phisign_ab\expandafter{\iffalse}\fi}%
\def\PhiSign_ab {\romannumeral0\phisign_ab}%
\def\phisign_ab #1#2;{%
    \xintiiifsgn{#1}%
    {% a < 0
     \xintiiifSgn{#2}%
           {-1}%
           {-1}%
           {% a < 0, b > 0, return 1 iff a^2+ab<b^2
            \xintifLt{\xintMul{#1}{\xintAdd{#1}{#2}}}{\xintSqr{#2}}%
            {1}%
            {-1}%
           }%
    }%
    {\xintiiSgn{#2}}%
    {% a > 0
     \xintiiifSgn{#2}%
           {% a > 0, b < 0, return 1 iff a^2+ab>b^2
            \xintifGt{\xintMul{#1}{\xintAdd{#1}{#2}}}{\xintSqr{#2}}%
            {1}%
            {-1}%
           }%
           {1}%
           {1}%
    }%
}%
%    \end{macrocode}
% \paragraph{\csh{PhiAbs}}\mbox{}
%    \begin{macrocode}
\def\PhiAbs{\romannumeral0\phiabs}%
\def\phiabs #1{%
    \expandafter\phiabs_a\expanded{{#1}}%
}%
\def\phiabs_a #1{\expandafter\phiabs_b\string#1}%
\catcode`[=1 \catcode`]=2 \catcode`\{=12 % }
\def\phiabs_b #1[\if#1{\expandafter\phiabs_X % }
                  \else\expandafter\phiabs_N\fi #1]%
\catcode`[=12 \catcode`]=12 \catcode`\{=1 % }
\let\phiabs_N \XINT_abs
\def\phiabs_X #1{\expandafter\phiabs_x\expandafter{\iffalse}\fi}%
\def\phiabs_x #1#2{\expanded{\ifnum\PhiSign_ab {#1}{#2};<\xint_c_
    \expandafter\xint_firstoftwo\else\expandafter\xint_secondoftwo\fi
    {{\XINT_Opp#1}{\XINT_Opp#2}}{{#1}{#2}}%
   }%
}%
%    \end{macrocode}
% \paragraph{\csh{PhiNorm}}\mbox{}
%    \begin{macrocode}
\def\PhiNorm{\romannumeral0\phinorm}%
\def\phinorm #1{%
    \expandafter\phinorm_a\expanded{{#1}}%
}%
\def\phinorm_a #1{\expandafter\phinorm_b\detokenize{#1;}{#1}}%
\catcode`[=1 \catcode`]=2 \catcode`\{=12 % }
\def\phinorm_b #1#2;[\if#1{\expandafter\phinorm_X % }
                     \else\expandafter\phinorm_N\fi]%
\catcode`[=12 \catcode`]=12 \catcode`\{=1 % }
\let\phinorm_N\xintsqr
\def\phinorm_X #1{\phinorm_x #1}%
\def\phinorm_x #1#2{\xintsub
  {\xintMul{#1}{\xintAdd{#1}{#2}}}%
  {\xintSqr{#2}}%
}%
%    \end{macrocode}
% \paragraph{\csh{PhiConj}}\mbox{}
%    \begin{macrocode}
\def\PhiConj{\romannumeral0\phiconj}%
\def\phiconj #1{%
    \expandafter\phiconj_a\expanded{{#1}}%
}%
\def\phiconj_a #1{\expandafter\phiconj_b\detokenize{#1;}#1}%
\catcode`[=1 \catcode`]=2 \catcode`\{=12 % }
\def\phiconj_b #1#2;[\if#1{\expandafter\phiconj_X % }
                     \else\expandafter\phiconj_N\fi]%
\catcode`[=12 \catcode`]=12 \catcode`\{=1 % }
\let\phiconj_N\space
\def\phiconj_X #1#2{\expanded{%
  {\xintAdd{#1}{#2}}{\XINT_Opp #2}%
}}%
%    \end{macrocode}
% \paragraph{\csh{PhiOpp}}\mbox{}
%    \begin{macrocode}
\def\PhiOpp{\romannumeral0\phiopp}%
\def\phiopp #1{%
    \expandafter\phiopp_a\expanded{{#1}}%
}%
\def\phiopp_a #1{\expandafter\phiopp_b\string#1}%
\catcode`[=1 \catcode`]=2 \catcode`\{=12 % }
\def\phiopp_b #1[\if#1{\expandafter\phiopp_X % }
                  \else\expandafter\phiopp_N\fi #1]%
\catcode`[=12 \catcode`]=12 \catcode`\{=1 % }
\let\phiopp_N \XINT_opp
\def\phiopp_X #1{\expandafter\phiopp_x\expandafter{\iffalse}\fi}%
\def\phiopp_x #1#2{\expanded{%
    {\XINT_Opp #1}{\XINT_Opp #2}%
}}%
%    \end{macrocode}
% \paragraph{\csh{PhiAdd}}\mbox{}
%    \begin{macrocode}
\def\PhiAdd{\romannumeral0\phiadd}%
\def\phiadd #1#2{%
    \expandafter\phiadd_a\expanded{{#1}{#2}}%
}%
\def\phiadd_a #1{\expandafter\phiadd_b\string#1;}%
\catcode`[=1 \catcode`]=2 \catcode`\{=12 % }
\def\phiadd_b #1[\if#1{\expandafter\phiadd_X % }
                  \else\expandafter\phiadd_N\fi #1]%
\def\phiadd_N #1;#2[\expandafter\phiadd_n\string#2;[#1]]%
\def\phiadd_n #1[\if#1{\expandafter\phiadd_nX % }
                  \else\expandafter\phiadd_nn\fi #1]%
\def\phiadd_nX #1[\expandafter\phiadd_nx\expandafter[\iffalse]\fi]%
\def\phiadd_X #1[\expandafter\phiadd_x\expandafter[\iffalse]\fi]%
%    \end{macrocode}
% |#1={a}{b}|.
%    \begin{macrocode}
\def\phiadd_x #1;#2[\expandafter\phiadd_xa\string#2;#1]%
\def\phiadd_xa#1[\if#1{\expandafter\phiadd_XX % }
                  \else\expandafter\phiadd_xn\fi #1]%
\def\phiadd_XX #1[\expandafter\phiadd_xx\expandafter[\iffalse]\fi]%
\catcode`[=12 \catcode`]=12 \catcode`\{=1 % }
\def\phiadd_nn #1;{\xintadd{#1}}%
\def\phiadd_nx #1#2;#3{\expandafter
   {\romannumeral0\xintadd{#1}{#3}}{#2}%
}%
\def\phiadd_xn #1;#2{\expandafter
   {\romannumeral0\xintadd{#1}{#2}}%
}%
\def\phiadd_xx #1#2;#3#4{\expanded{%
    {\xintAdd{#1}{#3}}%
    {\xintAdd{#2}{#4}}%
}}%
%    \end{macrocode}
% \paragraph{\csh{PhiSub}}\mbox{}
%    \begin{macrocode}
\def\PhiSub{\romannumeral0\phisub}%
\def\phisub #1#2{%
    \expandafter\phisub_a\expanded{{#1}{#2}}%
}%
\def\phisub_a #1{\expandafter\phisub_b\string#1;}%
\catcode`[=1 \catcode`]=2 \catcode`\{=12 % }
\def\phisub_b #1[\if#1{\expandafter\phisub_X % }
                  \else\expandafter\phisub_N\fi #1]%
\def\phisub_N #1;#2[\expandafter\phisub_n\string#2;[#1]]%
\def\phisub_n #1[\if#1{\expandafter\phisub_nX % }
                  \else\expandafter\phisub_nn\fi #1]%
\def\phisub_nX #1[\expandafter\phisub_nx\expandafter[\iffalse]\fi]%
\def\phisub_X #1[\expandafter\phisub_x\expandafter[\iffalse]\fi]%
%    \end{macrocode}
% |#1={a}{b}|.
%    \begin{macrocode}
\def\phisub_x #1;#2[\expandafter\phisub_xa\string#2;#1]%
\def\phisub_xa#1[\if#1{\expandafter\phisub_XX % }
                  \else\expandafter\phisub_xn\fi #1]%
\def\phisub_XX #1[\expandafter\phisub_xx\expandafter[\iffalse]\fi]%
\catcode`[=12 \catcode`]=12 \catcode`\{=1 % }
\def\phisub_nn #1;#2{\xintsub{#2}{#1}}%
\def\phisub_nx #1#2;#3{\expanded{%
   {\xintSub{#3}{#1}}{\XINT_Opp#2}%
}}%
\def\phisub_xn #1;#2{\expandafter
   {\romannumeral0\xintsub{#2}{#1}}%
}%
\def\phisub_xx #1#2;#3#4{\expanded{%
    {\xintSub{#3}{#1}}%
    {\xintSub{#4}{#2}}%
}}%
%    \end{macrocode}
% \paragraph{\csh{PhiMul}}\mbox{}
%    \begin{macrocode}
\def\PhiMul{\romannumeral0\phimul}%
\def\phimul #1#2{%
    \expandafter\phimul_a\expanded{{#1}{#2}}%
}%
\def\phimul_a #1{\expandafter\phimul_b\string#1;}%
\catcode`[=1 \catcode`]=2 \catcode`\{=12 % }
\def\phimul_b #1[\if#1{\expandafter\phimul_X % }
                  \else\expandafter\phimul_N\fi #1]%
\def\phimul_N #1;#2[\expandafter\phimul_n\string#2;[#1]]%
\def\phimul_n #1[\if#1{\expandafter\phimul_nX % }
                  \else\expandafter\phimul_nn\fi #1]%
\def\phimul_nX #1[\expandafter\phimul_nx\expandafter[\iffalse]\fi]%
\def\phimul_X #1[\expandafter\phimul_x\expandafter[\iffalse]\fi]%
%    \end{macrocode}
% |#1={a}{b}|.
%    \begin{macrocode}
\def\phimul_x #1;#2[\expandafter\phimul_xa\string#2;#1]%
\def\phimul_xa#1[\if#1{\expandafter\phimul_XX % }
                  \else\expandafter\phimul_xn\fi #1]%
\def\phimul_XX #1[\expandafter\phimul_xx\expandafter[\iffalse]\fi]%
\catcode`[=12 \catcode`]=12 \catcode`\{=1 % }
\def\phimul_nn#1;{\xintmul{#1}}%
\def\phimul_nx#1#2;#3{\expanded{%
    {\xintMul{#1}{#3}}{\xintMul{#2}{#3}}%
}}%
\def\phimul_xn#1;#2#3{\expanded{%
    {\xintMul{#1}{#2}}{\xintMul{#1}{#3}}%
}}%
\def\phimul_xx #1#2;#3#4{%
    \expandafter\phimul_xx_a\expanded{%
      \xintMul{#1}{#3};% ca
      \xintMul{#2}{#4};% db
      \xintMul{#1}{#4};% da
      \xintMul{#2}{#3};% cb
    }%
}%
\def\phimul_xx_a #1;#2;#3;#4;{\expanded{%
    {\xintAdd{#1}{#2}}%
    {\xintAdd{#3}{\xintAdd{#4}{#2}}}%
}}%
%    \end{macrocode}
% \paragraph{\csh{PhiDiv}}\mbox{}
%    \begin{macrocode}
\def\PhiDiv{\romannumeral0\phidiv}%
\def\phidiv #1#2{%
    \expandafter\phidiv_a\expanded{{#1}{#2}}%
}%
\def\phidiv_a #1{\expandafter\phidiv_b\string#1;}%
\catcode`[=1 \catcode`]=2 \catcode`\{=12 % }
\def\phidiv_b #1[\if#1{\expandafter\phidiv_X % }
                  \else\expandafter\phidiv_N\fi #1]%
\def\phidiv_N #1;#2[\expandafter\phidiv_n\string#2;[#1]]%
\def\phidiv_n #1[\if#1{\expandafter\phidiv_nX % }
                  \else\expandafter\phidiv_nn\fi #1]%
\def\phidiv_nX #1[\expandafter\phidiv_nx\expandafter[\iffalse]\fi]%
\def\phidiv_X #1[\expandafter\phidiv_x\expandafter[\iffalse]\fi]%
%    \end{macrocode}
% |#1={a}{b}|.
%    \begin{macrocode}
\def\phidiv_x #1;#2[\expandafter\phidiv_xa\string#2;#1]%
\def\phidiv_xa#1[\if#1{\expandafter\phidiv_XX % }
                  \else\expandafter\phidiv_xn\fi #1]%
\def\phidiv_XX #1[\expandafter\phidiv_xx\expandafter[\iffalse]\fi]%
\catcode`[=12 \catcode`]=12 \catcode`\{=1 % }
\def\phidiv_nn#1;#2{\xintdiv{#2}{#1}}%
\def\phidiv_nx#1#2{%
    \expandafter\phidiv_nx_a\expanded{%
     {\xintSub{\xintMul{#1}{\xintAdd{#1}{#2}}}{\xintSqr{#2}}}%
    }{#1}{#2}%
}% 
\def\phidiv_nx_a#1#2#3;#4{\expanded{%
    {\xintIrr{\xintDiv{\xintMul{#4}{\xintAdd{#2}{#3}}}{#1}}[0]}%
    {\xintIrr{\xintOpp{\xintDiv{\xintMul{#4}{#3}}{#1}}}[0]}%
}}%
\def\phidiv_xn #1;#2#3{\expanded{%
    {\xintIrr{\xintDiv{#2}{#1}}[0]}%
    {\xintIrr{\xintDiv{#3}{#1}}[0]}%
}}%
\def\phidiv_xx #1#2;#3#4{%
    \expandafter\phidiv_xx_a\expanded{%
     \expandafter\phimul_xx
       \expanded{{\xintAdd{#1}{#2}}{\XINT_Opp #2}};{#3}{#4}% 
     {\xintSub{\xintMul{#1}{\xintAdd{#1}{#2}}}{\xintSqr{#2}}}%
    }%
}%
\def\phidiv_xx_a #1#2#3{%
    \expanded{%
    {\xintIrr{\xintDiv{#1}{#3}}[0]}%
    {\xintIrr{\xintDiv{#2}{#3}}[0]}%
   }%
}%
%    \end{macrocode}
% \paragraph{\csh{PhiPow}}\mbox{}
%    \begin{macrocode}
\def\PhiPow{\romannumeral0\phipow}%
\def\phipow #1#2{%
    \expandafter\phipow_a\expanded
    {{#1}{\xintNum{#2}}}%
}%
\def\phipow_a #1{\expandafter\phipow_b\string#1;}%
\catcode`[=1 \catcode`]=2 \catcode`\{=12 % }
\def\phipow_b #1[\if#1{\expandafter\phipow_X % }
                  \else\expandafter\phipow_N\fi #1]%
\catcode`[=12 \catcode`]=12 \catcode`\{=1 % }
\def\phipow_N #1;{\xintpow{#1}}%
\def\phipow_X #1{\expandafter\phipow_x\expandafter{\iffalse}\fi}%
%    \end{macrocode}
% Let's handle negative exponents too, now that we use |\xinteval|. 
%    \begin{macrocode}
\def\phipow_x #1;#2{\phipow_fork #2;#1}%
\def\phipow_fork #1{%
    \xint_UDzerominusfork
       0#1\phipow_neg
       #1-\phipow_zero
        0-\phipow_pos
    \krof #1%
}%
\def\phipow_zero 0;#1#2{{1}{0}}%
\def\phipow_neg -{%
    \expandafter\phiinv_ab\romannumeral0\phipow_pos
}%
\def\phiinv_ab #1#2{%
    \expandafter\phiinv_c\expanded{%
     {\xintSub{\xintMul{#1}{\xintAdd{#1}{#2}}}{\xintSqr{#2}}}%
    }{#1}{#2}%
}%
\def\phiinv_c #1#2#3{\expanded{%
    {\xintIrr{\xintDiv{\xintAdd{#2}{#3}}{#1}}[0]}%
    {\xintIrr{\xintOpp{\xintDiv{#3}{#1}}}[0]}%
}}%
\def\phipow_pos #1;{%
    \expandafter\phipow_xa
    \expanded{10\xintDecToBin{#1}},;%
}%
\def\phipow_xa #1#2#3#4;{%
  \if#3,\expandafter\phipow_done\fi
  \if#31\expandafter\phipow_xo
   \else\expandafter\phipow_xe\fi
  {#1}{#2}#4;%
}%
\def\phipow_done \if#1\fi #2#3;#4#5{{#2}{#3}}%
\def\phipow_xo #1#2{%
  \expandafter\phipow_xo_a\expanded{%
  \xintSqr{#1};\xintMul{#1}{#2};\xintSqr{#2};%
  }%
}%
\def\phipow_xo_a #1;#2;#3;{%
  \expandafter\phipow_xo_b\expanded{%
  \xintAdd{#1}{#3};\xintAdd{#2}{\xintAdd{#2}{#3}};%
  }%
}%
\def\phipow_xo_b#1;#2;#3;#4#5{%
  \expandafter\phipow_xa\romannumeral0%
  \phimul_xx {#1}{#2};{#4}{#5}#3;{#4}{#5}%
}%
\def\phipow_xe #1#2{%
  \expandafter\phipow_xe_a\expanded{%
  \xintSqr{#1};\xintMul{#1}{#2};\xintSqr{#2};%
  }%
}%
\def\phipow_xe_a #1;#2;#3;{%
  \expandafter\phipow_xa\expanded{%
  {\xintAdd{#1}{#3}}{\xintAdd{#2}{\xintAdd{#2}{#3}}}%
  }%
}%
%    \end{macrocode}
% \subsubsection{Overloading +,\mbox{}
% \textendash, \texorpdfstring{\protect\lowast}{*}, \textasciicircum,
% and \texorpdfstring{\protect\lowast\protect\lowast}{**}}
%
% The |**| is pre-aliased to |^| at \xintexprname level via
% |\XINT_expr_itself_**|, so nothing to do here once |^| is handled.
%
% The unary |-| requires extra care.
%    \begin{macrocode}
\zeckdefinfix{+}{\PhiAdd}{12}{12}%
\zeckdefinfix{-}{\PhiSub}{12}{12}%
\xintFor #1 in {xii,xiv,xvii}\do{%
    \expandafter\def\csname XINT_expr_exec_-#1\endcsname
    ##1##2##3%
    {%
      \expandafter ##1\expandafter ##2\expandafter
       {%
        \romannumeral`&&@\XINT:NEhook:f:one:from:one
        {\romannumeral`&&@\PhiOpp##3}%
       }%
    }%
}%
\zeckdefinfix{*}{\PhiMul}{14}{14}%
\zeckdefinfix{/}{\PhiDiv}{14}{14}%
\zeckdefinfix{^}{\PhiPow}{18}{17}%
%    \end{macrocode}
% \subsubsection{Variables and functions for \cs{xinteval}}
%
% The macros computing Fibonacci numbers, Zeckendorf indices, and Bergman
% exponents, were done originally assuming to be used with arguments in strict
% integer format.  But when operations are executed in |\xinteval| the
% intermediate results will use the ``raw'' format described in the
% \xintexprname manual, not the ``strict integer format''.  We thus need
% wrappers to apply |\xintNum| for normalization, even though this adds annoying
% overhead.  These wrappers can assume that the argument is already expanded.
%
% For macros handling input being either one unbraced integer or a pair of
% braced integers this is more complicated.  We separated |\PhiIISign_ab| from
% |\PhiSign| to this aim.  The former for optimized internal usage, only using
% integer algebra.  The latter uses the \xintfracname macros, so there is
% no problem and we do not want to truncate arguments to integers.  Similarly for
% |\PhiAbs| no need to do something special.
%
% |\PhiMaxE| is integer-only, but in the end I decided to not provide an
% |\xinteval| interface and to remove the one for |\ZeckMaxK|.
%
% For the support for |phiexponents()|, which is also integer only we have to
% use |\xintNum|, the problem is that we can't do that prior to know if used
% with an integer or a nutple. So |\Phi@BList| was done to handle that.
%    \begin{macrocode}
\xintdefvar phi:=[0,1];%
\xintdefvar psi:=[1,-1];%
\def\XINT_expr_func_phinorm #1#2#3%
{%
    \expandafter #1\expandafter #2\expandafter{%
    \romannumeral`&&@\XINT:NEhook:f:one:from:one
    {\romannumeral`&&@\PhiNorm#3}}%
}%
\def\XINT_expr_func_phiconj #1#2#3%
{%
    \expandafter #1\expandafter #2\expandafter{%
    \romannumeral`&&@\XINT:NEhook:f:one:from:one
    {\romannumeral`&&@\PhiConj#3}}%
}%
\def\XINT_expr_func_phisign #1#2#3%
{%
    \expandafter #1\expandafter #2\expandafter{%
    \romannumeral`&&@\XINT:NEhook:f:one:from:one
    {\romannumeral`&&@\PhiSign#3}}%
}%
\def\XINT_expr_func_phiabs #1#2#3%
{%
    \expandafter #1\expandafter #2\expandafter{%
    \romannumeral`&&@\XINT:NEhook:f:one:from:one
    {\romannumeral`&&@\PhiAbs#3}}%
}%
\def\ZeckTheFNnum#1{\ZeckTheFN{\xintNum{#1}}}%
\def\XINT_expr_func_fib #1#2#3%
{%
    \expandafter #1\expandafter #2\expandafter{%
    \romannumeral`&&@\XINT:NEhook:f:one:from:one
    {\romannumeral`&&@\ZeckTheFNnum#3}}%
}%
\def\ZeckTheFSeqnum#1#2{\ZeckTheFSeq{\xintNum{#1}}{\xintNum{#2}}}%
\def\XINT_expr_func_fibseq #1#2#3%
{%
    \expandafter #1\expandafter #2\expandafter{%
    \romannumeral`&&@\XINT:NEhook:f:one:from:two
    {\romannumeral`&&@\ZeckTheFSeqnum#3}}%
}%
%    \end{macrocode}
% Let's the |\xinteval| interface silently handle negative
% or vanishing input.
%    \begin{macrocode}
\def\ZeckBListnum#1{%
    \expandafter\zeckblistnum\romannumeral0\xintnum{#1};%
}%
\def\zeckblistnum #1#2;{%
    \xint_UDzerominusfork
      0#1{\ZeckBList{#2}}#1-{{}}0-{\ZeckBList{#1#2}}%
    \krof
}%
\def\XINT_expr_func_zeckindices #1#2#3%
{%
    \expandafter #1\expandafter #2\expandafter{%
    \romannumeral`&&@\XINT:NEhook:f:one:from:one
    {\romannumeral`&&@\ZeckBListnum#3}}%
}%
%    \end{macrocode}
% TODO: I have forgotten now but I vaguely remember if compatibility
% with usage of the defined function in |\xintdeffunc| is hoped for
% that it should first expand its argument even though in our context
% if purely numerical this is unneeded (and f-expansion will
% hit a brace generally in       case input is  nutphi. Adding anyhow.
% I have other things in mind currently, to examine later, already
% quite enough hours on this package.
%    \begin{macrocode}
\def\Phi@BList#1{\expandafter\expandafter\expandafter
     \phi@blist_b\expandafter\string\romannumeral`&&@#1;}%
\catcode`[=1 \catcode`]=2 \catcode`\{=12 % }
\def\phi@blist_b #1[\if#1{\expandafter\phi@blist_X % }
                    \else\expandafter\phi@blist_N\fi #1]%
\catcode`[=12 \catcode`]=12 \catcode`\{=1 % }
\def\phi@blist_N #1;{%
    \expandafter\xint_gobble_i\expanded
    \expandafter\phiblist_ab \expanded{{\xintNum{#1}}}{0};%
}%
\def\phi@blist_X #1{%
    \expandafter\phi@blist_x\expandafter{\iffalse}\fi
}%
\def\phi@blist_x #1#2;{%
    \expandafter\xint_gobble_i\expanded
    \expandafter\phiblist_ab \expanded{{\xintNum{#1}}{\xintNum{#2}}};%
}%
\def\XINT_expr_func_phiexponents #1#2#3%
{%
    \expandafter #1\expandafter #2\expandafter{%
    \romannumeral`&&@\XINT:NEhook:f:one:from:one
    {\romannumeral`&&@\Phi@BList#3}}%
}%
%    \end{macrocode}
% ATTENTION! we leave the modified catcodes in place! (the question mark
% has regained its catcode other though).
%
% \catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11
% \let</core>\relax
% \def<*interactive>{\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 }
%</core>
%<*interactive>
% \makeatletter\global\c@CodelineNo\z@\makeatother
% \section{Interactive code}
% \label{sec:code:interactive}
% Extracts to |zeckendorf.tex|.
%    \begin{macrocode}
\input zeckendorfcore.tex
\let\xintfirstoftwo\xint_firstoftwo
\let\xintsecondoftwo\xint_secondoftw
\let\zeckexprmapwithin\XINT:expr:mapwithin
\def\zeckNumbraced#1{{\xintNum{#1}}}
\xintexprSafeCatcodes

\let\ZeckShouldISayOrShouldIGo\iftrue
\def\ZeckCmdQ{\let\ZeckShouldISayOrShouldIGo\iffalse}
\let\ZeckCmdX\ZeckCmdQ
\let\ZeckCmdx\ZeckCmdQ
\let\ZeckCmdq\ZeckCmdQ

\newif\ifzeckphimode
\newif\ifzeckindices
\zeckindicestrue
\newif\ifzeckfromN
\zeckfromNtrue
\newif\ifzeckmeasuretimes
\newif\ifzeckevalonly

\def\ZeckCmdP{%
    \zeckphimodetrue
    \ifzeckindices\ZeckCmdL\else\ZeckCmdB\fi
}
\def\ZeckCmdZ{%
    \zeckphimodefalse
    \ifzeckindices\ZeckCmdL\else\ZeckCmdB\fi
}
\let\ZeckCmdp\ZeckCmdP
\let\ZeckCmdz\ZeckCmdZ

\def\PhiTypesetXPrint #1#2{a=#1, b=#2}
\def\ZeckCmdL{%
    \zeckindicestrue
    \ifzeckphimode
      \def\ZeckFromN{\PhiExponents}%
      \def\ZeckToN##1{\PhiTypesetX{\PhiXfromExponents{##1}}}%
    \else
      \def\ZeckFromN{\ZeckIndices}%
      \def\ZeckToN{\ZeckNFromIndices}%
    \fi
}
\let\ZeckCmdl\ZeckCmdL

\def\ZeckCmdB{%
    \zeckindicesfalse
    \ifzeckphimode
      \def\ZeckFromN{\PhiBasePhi}%
      \def\ZeckToN##1{\PhiTypesetX{\PhiXfromBasePhi{##1}}}%
    \else
      \def\ZeckFromN{\ZeckWord}%
      \def\ZeckToN{\ZeckNfromWord}%
    \fi
}
\let\ZeckCmdW\ZeckCmdB
\let\ZeckCmdb\ZeckCmdB
\let\ZeckCmdw\ZeckCmdB

\def\ZeckConvert{%
    \csname Zeck\ifzeckfromN From\else To\fi N\endcsname
}
\def\ZeckCmdT{\ifzeckfromN\zeckfromNfalse\else\zeckfromNtrue\fi}
\let\ZeckCmdt\ZeckCmdT

\expandafter\def\csname ZeckCmd@\endcsname{%
  \ifdefined\xinttheseconds
      \ifzeckmeasuretimes\zeckmeasuretimesfalse
          \else          \zeckmeasuretimestrue
      \fi
  \else
      \immediate\write128{Sorry, this requires xintexpr 1.4n or later.}%
  \fi
}

\def\ZeckCmdE{\ifzeckevalonly\zeckevalonlyfalse\else\zeckevalonlytrue\fi}
\let\ZeckCmde\ZeckCmdE

\def\ZeckCmdH{\immediate\write128{\ZeckHelpPanel}}
\let\ZeckCmdh\ZeckCmdH

\ZeckCmdL

\def\ZeckCommands{Enter input or command
                  (q, z, p, l, w, t, e, @, or h for help).}
\def\ZeckPrompt{%
  \ifzeckevalonly
    <<<Eval-only (e to quit)>>>^^J%
    [IN] expression =
  \else
   \ifzeckfromN
    \ifzeckphimode
      \ifzeckindices <convert to Bergman phi-exponents>^^J%
      \else          <convert to Bergman phi-representation>^^J%
      \fi
      \ZeckCommands^^J
      [IN] a + b phi =
    \else
      \ifzeckindices <convert to Zeckendorf indices>^^J%
      \else          <convert to Zeckendorf word>^^J%
      \fi
      \ZeckCommands^^J
      [IN] N =
    \fi
   \else
    \ifzeckphimode <convert to a + b phi>^^J
      \ZeckCommands^^J
      [IN]
       \ifzeckindices phi exponents =
       \else          phi-representation =
       \fi
    \else          <convert to integer>^^J
      \ZeckCommands^^J
      [IN]
       \ifzeckindices indices =
       \else          binary word =
       \fi
    \fi
   \fi
  \fi
}
\newlinechar10
\immediate\write128{}
\immediate\write128{Welcome to Zeckendorf 0.9c (2025/10/17, JFB).}

\def\ZeckHelpPanel{Commands (lowercase also):^^J
 Q to quit. Also X.^^J
 H for this help.^^J
 Z to switch to Z-mode (starting default).^^J
 P to switch to Phi-mode.^^J
 L for indices (Z) or exponents (Phi).^^J
 W for Zeckendorf word or Bergman phi-representation.^^J
 T to toggle the direction of conversions.^^J
 E to toggle to and from  \string\xinteval-only mode.^^J
 @ to toggle measurement of execution times.^^J
^^J
 - binary words, phi-representations, are parsed only by \string\edef.^^J
 - all other inputs are handled by \noexpand\xinteval so for example one^^J
\space\space
   can use 2^100 or 100! or binomial(100,50).  And a list of indices^^J
\space\space
   can be for example seq(3*a+1, a=0..10).^^J
^^J
\space\space The fib() function computes Fibonacci numbers.^^J
\space\space The character $ serves as symbol for Knuth multiplication.^^J%
**** empty input is not supported!
     no linebreaks in input! ****}

\immediate\write128{\ZeckHelpPanel}

\def\zeckpar{\par}
\long\def\xintbye#1\xintbye{}
\long\def\zeckgobbleii#1#2{}
\long\def\zeckfirstoftwo#1#2{#1}
\def\zeckonlyonehelper #1#2#3%
    \zeckonlyonehelper{\xintbye#2\zeckgobbleii\xintbye0}

\xintFor*#1 in {0123456789}\do{%
   \expandafter\def\csname ZeckCmd#1\endcsname{%
      \immediate\write128{%
** Due to under-funding, a lone #1 is not accepted. Inputs must have^^J%
** two characters at least.  Think about a donation? Try 0#1.}}
}%
\xintloop
\message{\ZeckPrompt}
\read-1to\zeckbuf
\ifx\zeckbuf\zeckpar
  \immediate\write128{**** empty input is not supported, please try again.}
\else
  \edef\zeckbuf{\zeckbuf}
%    \end{macrocode}
% Space token at end of |\zeckbuf| is annoying. We could have used
% |\xintLength| which does not count space tokens.
%    \begin{macrocode}
  \if 1\expandafter\zeckonlyonehelper\zeckbuf\xintbye\zeckonlyonehelper1%
   \ifcsname ZeckCmd\expandafter\zeckfirstoftwo\zeckbuf\relax\endcsname
     \csname ZeckCmd\expandafter\zeckfirstoftwo\zeckbuf\relax\endcsname
   \else
     \immediate\write128{%
     **** Unrecognized command letter
          \expandafter\zeckfirstoftwo\zeckbuf\relax. Try again.^^J}
   \fi
  \else
%    \end{macrocode}
% Using the conditional so that this can also be used by default
% with older xint.
%
% With |0.9b| the time needed for parsing the input was not counted,
% but this meant that measuring in the evaluation-only mode always
% printed |0.0s|.
%
% |0.9c|  has refactored here entirely.
%    \begin{macrocode}
   \ifzeckmeasuretimes\xintresettimer\fi
   \if1\ifzeckevalonly0\fi\ifzeckfromN0\fi\ifzeckindices0\fi1%
      \edef\ZeckIn{{\zeckbuf}}%
   \else
      \expandafter\def\expandafter\ZeckIn\expandafter{%
      \romannumeral0\xintbareeval\zeckbuf\relax}%
%    \end{macrocode}
% |0.9c| uses |\xinteval|.  It adds phi-mode to the interactive interface, but
% as |1/phi| or anything doing an operation will inject ``raw xintfrac
% format'', we have to be careful about that, because we use |\PhiExponents|
% and |\PhiBasePhi| which are assuming being used with either an integer |a|
% or a pair |{a}{b}|.  Using here some core level auxiliary from \xintexprname
% to avoid a dozen lines like what was done for |\Phi@BList|.  For this to
% work we need a variant of |\xintNum| which outputs with extra braces.  This
% was for the author a refreshing journey to revisit forgotten deep code
% written years ago for \xintexprname.  But it would be more efficient to do
% something akin to the |\Phi@BList| business.
%
% By the way we have to do this not only for phi-mode, but also for
% integer-mode, because some input such as |1e40| will be internally |1[40]|
% which |\ZeckIndices| does not understand as it does not apply |\xintNum|. In
% fact any input doing an operation such as an addition will be in ``raw
% xintfrac format'' internally.  So we have to do a normalization also for
% lists of exponents or indices.
%    \begin{macrocode}
      \ifzeckevalonly\else
         \expandafter\def\expandafter\ZeckIn
           \expanded
           \expandafter\zeckexprmapwithin
           \expandafter\zeckNumbraced\ZeckIn
%    \end{macrocode}
% For lists of exponents and indices the predefined macros expect
% comma separated lists.  We can either "print" using (full) |\xinteval|,
% or use |\xintListwithSep|, or write a little helper requiring
% only |\edef| expansion.  We add one level of bracing removed later.
%    \begin{macrocode}
         \ifzeckfromN\else
            \expandafter\def\expandafter\ZeckIn\expandafter{%
              \expandafter{\romannumeral0\xintlistwithsep,\ZeckIn}%
            }%
         \fi
      \fi
   \fi
   \immediate\write128{%
     [OUT] \ifzeckevalonly
       \expanded\expandafter\XINTexprprint\expandafter.\ZeckIn
     \else
       \expandafter\ZeckConvert\ZeckIn
     \fi
   }%
   \ifzeckmeasuretimes
     \edef\tmp{\xinttheseconds}%
     \immediate\write128{%
        \ifzeckevalonly Evaluation \else Conversion \fi
        took \tmp s%
     }%
   \fi
  \fi
\fi
\ZeckShouldISayOrShouldIGo
\repeat

\immediate\write128{Bye. Results are also in log file (hard-wrapped too, alas).}
\bye
%    \end{macrocode}
% \catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11
% \let</interactive>\relax
% \def<*sty>{\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 }
%</interactive>
%<*sty>
% \makeatletter\global\c@CodelineNo\z@\makeatother
% \section{\LaTeX{} code}
% Extracts to |zeckendorf.sty|.
% \label{sec:code:latex}
%    \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{zeckendorf}
   [2025/10/17 v0.9c Zeckendorf representations of big integers (JFB)]%
\RequirePackage{xintexpr}
\RequirePackage{xintbinhex}% superfluous if with xint 1.4n or later
\input zeckendorfcore.tex
\ZECKrestorecatcodesendinput%
%    \end{macrocode}
% \catcode`\<=0 \catcode`\>=11 \catcode`\*=11 \catcode`\/=11
% \let</sty>\relax
% \def<*dtx>{\catcode`\<=12 \catcode`\>=12 \catcode`\*=12 \catcode`\/=12 }
%</sty>
%<*dtx>
% \MakePercentComment
\CheckSum {2953}%
\makeatletter\check@checksum\makeatother%
\Finale%
%% End of file zeckendorf.dtx
