# Fit IEEE-754 table in A4 width

surely asked a thousend times. I found a lot of answers to this but none seem to work. I've tried using tabular and tabularx but nope.

\documentclass[12pt,a4paper]{article}

\usepackage{ucs}
\usepackage[utf8x]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{amsmath,amssymb,amstext,fancyhdr}
\usepackage{tabularx}
\pagestyle{fancy}

\begin{document}
\section*{Computersysteme II (01609) WS2018/19 EA 1}
\label{sec:Einsendeaufgabe 1}
\subsection*{Aufgabe 1 - Allgemeine Fragen}
...
\pagebreak
Gegeben sei die Dezimalzahl $Z_{10}=-208,40625$.
\begin{itemize}
\item[a)] So richtig verstanden habe ich das Schema nicht...\\
$Z_{32}=\left(-1\right)^1\cdot2^{135}\cdot\left(100001100,0110100\ldots\right)$
\item[b)] \begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|}
% {|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|}
% {|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|X|}
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24 & 23 & 22 & 21 & 20 & 19 & 18 & 17 & 16 & 15 & 14 & 13 & 12 & 11 & 10 & 9 & 8 & 7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
S & E & E & E & E & E & E & E & E & M & M & M & M & M & M & M & M & M & M & M & M & M & M & M & M\\
\hline
1 & 1 & 0 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 1 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0
\end{tabular}
\end{itemize}
\end{document}


When I add {0.3\textwidth} after{tabular} it complains about the number and does scale the \hline only. Some solutions suggested using \begin{table}. That didn't work either and moved the table above the header...

Regards, Stephan

• You seem to try to fit an elephant into a suitcase ... I don't think this will work ... Off-topic: you might either want to use siunitx to format your numbers or have a look at the icomma package to avoid the incorrect spacing around , Commented Nov 27, 2018 at 15:34
• Can't you split your table into two ones below each other? Commented Nov 27, 2018 at 15:36
• Well, the prof or TA did it. ;) Commented Nov 27, 2018 at 16:44

Not without using a wider line length.

\documentclass[12pt,a4paper]{article}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}

\usepackage{amsmath,amssymb,fancyhdr,array}

\pagestyle{fancy}

\begin{document}

\section*{Computersysteme II (01609) WS2018/19 EA 1}
\label{sec:Einsendeaufgabe 1}

Gegeben sei die Dezimalzahl $Z_{10}=-208,40625$.
\begin{itemize}
\item[a)] So richtig verstanden habe ich das Schema nicht...\\
$Z_{32}=\left(-1\right)^1\cdot2^{135}\cdot\left(100001100,0110100\ldots\right)$
\item[b)]
{\footnotesize\setlength{\tabcolsep}{1pt}\begin{tabular}[t]{|*{32}{w{c}{1em}|}}
\firsthline
31 & 30 & 29 & 28 & 27 & 26 & 25 & 24 & 23 & 22 & 21 & 20 & 19 & 18 & 17 & 16 & 15 & 14 & 13 & 12 & 11 & 10 & 9 & 8 & 7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\
\hline
S & E & E & E & E & E & E & E & E & M & M & M & M & M & M & M & M & M & M & M & M & M & M & M & M\\
\hline
1 & 1 & 0 & 0 & 0 & 0 & 1 & 1 & 1 & 0 & 0 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 1 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\
\hline
\end{tabular}}

\end{itemize}

\end{document}


Don't use utf8x, it's been unmaintained for several years, whereas utf8 is actively developed.

You can play with the setting of \tabcolsep.

• Cheers. There's a closing } after \end{tabular}. That's probably the reason why my own scaling attempts failed badly. Commented Nov 27, 2018 at 16:45

You can let TeX compute it for you:

\documentclass[12pt,a4paper]{article}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}

\usepackage[autolanguage, np]{numprint}
\usepackage{amsmath,amssymb,fancyhdr,array}

\pagestyle{fancy}

\usepackage{xintfrac, xintbinhex, xinttools}

\makeatletter
\def\DtoB@get@ND #1/#2[#3]{% #2 must be = 1 here, if input was in
% decimal notation
\edef\DtoB@s{\xintiiSgn{#1}}%
\edef\DtoB@A{\xintiiAbs{#1}}%
\def\DtoB@L{#3}%
\ifnum#3<\z@
\let\DtoB@N\DtoB@A
\edef\DtoB@D{\xintiiE{1}{-#3}}%
\else
\edef\DtoB@N{\xintiiE{\DtoB@A}{#3}}%
\def\DtoB@D{1}%
\fi
}%
\newcommand\ParseFromDecimalToIEEEBinary[1]{%
% assume #1 is a decimal number (I will write code for fractions
% another day)
\expandafter\DtoB@get@ND\romannumeral0\xintrez{#1}%
% we should here handle \DtoB@s = 0 but no time tonight, assume input non-zero
\edef\DtoB@S@bit{\the\numexpr(1-\DtoB@s)/2}% 1 if number < 0, 0 if number > 0
\edef\DtoB@U{\xintDecToBin{\DtoB@N}}%
\edef\DtoB@V{\xintDecToBin{\DtoB@D}}%
\edef\DtoB@Uk{\the\numexpr\expandafter\xintLength\expandafter{\DtoB@U}-\@ne}%
\edef\DtoB@Vl{\the\numexpr\expandafter\xintLength\expandafter{\DtoB@V}-\@ne}%
% next step should perhaps compare k and l first
% important that we are comparing here two strings of 1s and 0s of
% exact same length
\ifnum\pdfstrcmp{\DtoB@U\romannumeral\xintreplicate{\DtoB@Vl}{0}}
{\DtoB@V\romannumeral\xintreplicate{\DtoB@Uk}{0}}=\m@ne
\edef\DtoB@E{\the\numexpr\DtoB@Uk-\DtoB@Vl-\@ne}%
\else
\edef\DtoB@E{\the\numexpr\DtoB@Uk-\DtoB@Vl}%
\fi
\edef\DtoB@Eshifted@bits{\expandafter\@gobble
\romannumeral0\xintdectobin{\the\numexpr \DtoB@E + 127 + 256\relax}}%
\ifnum\DtoB@E>23
\edef\DtoB@f@frac{\DtoB@A/\xintiiPow{2}{\DtoB@E-23}[\DtoB@L]}%
%  use rather bintodec conversion of 10000...000 in above?
\else
\edef\DtoB@f@frac{\xintiiMul{\DtoB@A}{\xintiiPow{2}{23-\DtoB@E}}/1[\DtoB@L]}%
\fi
\edef\DtoB@f@int{\xintNum{\DtoB@f@frac}}% truncates to an int
\edef\DtoB@M@bits{\expandafter\@gobble
\romannumeral0\xintdectobin{\DtoB@f@int}}%
%\edef\DtoBresult{\DtoB@S@bit\DtoB@Eshifted@bits\DtoB@M@bits}%
\let\IEEEsign\DtoB@S@bit
\let\IEEEexponent\DtoB@Eshifted@bits
\let\IEEEmantissa\DtoB@M@bits
}%

\makeatother

\newcommand\AUFGABE[1]{%
\ParseFromDecimalToIEEEBinary{#1}%

\noindent
Gegeben sei die Dezimalzahl $Z_{10}=\np{#1}$.
\begin{itemize}
\item[a)] So richtig verstanden habe ich das Schema nicht...\\
% $Z_{32}=\left(-1\right)^1\cdot2^{135}\cdot\left(100001100,0110100\ldots\right)$
\item[b)]
{\footnotesize\setlength{\tabcolsep}{1pt}\begin{tabular}[t]{|*{32}{w{c}{1em}|}}
\firsthline
\xintListWithSep{&}{\xintSeq[-1]{31}{0}}\\
\hline
S \romannumeral\xintreplicate{8}{&E}\romannumeral\xintreplicate{23}{&M}\\
\hline
\IEEEsign & \xintListWithSep{&}{\IEEEexponent} & \xintListWithSep{&}{\IEEEmantissa}\\
\hline
\end{tabular}\par}%
\end{itemize}
}

\begin{document}

\section*{Computersysteme II (01609) WS2018/19 EA 1}
\label{sec:Einsendeaufgabe 1}

\AUFGABE{-208.40625}

\AUFGABE{1234.37892295}

\AUFGABE{37317.384038}

\end{document}


Attention, I did not handle denormalized numbers, and also the input must not be zero!

I have not stress-tested it really, only compared first and last of the above with an online-converter.

As per the fractional binary notation which I think the a) item is about I dropped it, but this can be added.

You can of course now modify the code to handle any other similary IEEE format with more space for the exponent and/or binary mantissa.

Attention: as conversion from decimal to binary can not be exact, I chose "truncation towards zero" to choose binary float, perhaps rounding would be better (or rounding to even rather).

There is no error check on input causing overflow/underflow and no handling of denormalized numbers.

Also, due to a temporary lack of energy, I did not do it expandably...

Here is as an update a conversion routine \DecimalToIEEEBinary according to IEEE-754 format with arbitrary, user configurable, number of bits. I illustrate it with some binary32, binary64 and one binary128 examples. Please note:

• For lack of time I have not tested it apart from comparing a few conversions with result of an online converter,

• I have not implemented subnormal numbers, or overflow etc...

• I have not implemented inexact flag etc...,

• The input allows any fraction (as accepted by xintfrac macros) but note that the result is the exact rounding of the exact fraction to nearest binary float, it is not obtained by first converting numerator then denominator then doing a float division (as IEEE-754 or perhaps its later 2008 edition mandates that division should be exactly rounded, things like 355/113 give no surprise because each of 355 and 113 is exactly represented, but 355456.7/113456.3 will probably give different result in 32bit binary (about 7 or 8 decimal digits precision) when converted here or when computed by your programming language in single precision with some loss already at numerator and denominator.

• For decimal numbers 0.37 for example, I trust normal languages do this conversion to binary float with exact rounding (Python for example). In case of doubt, compare to what xint-based \DecimalToIEEEBinary below says, because it will be correct (fingers crossed, I have really not at all debugged that thing, and barely tested) as it relies on arbitrary precision arithmetic (Python is a language with such arbitrary precision integer arithmetic),

• As I believe the rounding mode when converting to binary is expected to be "round to nearest, tie goes to even", I have implemented that here. Not debugged. (it is simple but even simplest TeX code needs 10 times the concentration of programmer than code in Python or C or whatever...)

Code:

\documentclass{article}
\usepackage{xintfrac}
\usepackage{xintbinhex}

\usepackage{xintexpr}% for one example only

\newcommand\IEEEexponentwidth{8}
\newcommand\IEEEtotalwidth{32}% 1 + exp with + mantissa (without leading bit) width
\newcommand\IEEEupdate{%
% for simplicity I assume here at most 30 exponent bits..., because I will
% do computations with \numexpr for the exponent; I will not check
% overflow conditions for these exponent computations although of course
% I could as xint is arbitrary precision
\edef\IEEEemax{\the\numexpr\xintiiPow{2}{\IEEEexponentwidth-1}-1}%
\edef\IEEEepoweroftwo{\the\numexpr2*\IEEEemax+2}% needed internally
\edef\IEEEemin{\the\numexpr-\IEEEemax+1}%
\edef\IEEEebias{\IEEEemax}%
\edef\IEEEprecision{\the\numexpr\IEEEtotalwidth-\IEEEexponentwidth}%
}%

\makeatletter
\catcode_ 11
\catcode! 3
\newcommand\IEEEsetup[1]{\D_to_ieeeB_parsekeys #1,=!,\IEEEupdate}%
\def\D_to_ieeeB_parsekeys #1=#2#3,{\ifx!#2\expandafter\D_to_ieeeB_parsedone\fi
\csname IEEEsetup_key_\xint_zapspaces #1 \xint_gobble_i\endcsname
\xint_firstoftwo
{\PackageWarning{IEEEsetup}{The #1 key is unknown! ignoring}}{#2#3}%
\D_to_ieeeB_parsekeys
}%
\def\D_to_ieeeB_parsedone #1\D_to_ieeeB_parsekeys {}%
\catcode! 11
\def\IEEEsetup_key_Ewidth  #1#2{\edef\IEEEexponentwidth}%
\def\IEEEsetup_key_totalwidth #1#2{\edef\IEEEtotalwidth}%

\IEEEsetup{Ewidth=8, totalwidth=32}

\newcommand\IEEEprintsetup{%
Emax = \IEEEemax, Emin = \IEEEemin, P = \IEEEprecision.

There is one leading sign bit, followed by \IEEEexponentwidth\ bits for the
exponent (which is represented shifted by \IEEEebias), followed by
\IEEEmantissawidth\ bits which represent the fractional part of the mantissa,
its leading bit 1 being tacit.

This setup is obtained by specifying Ewidth = \IEEEexponentwidth\ and
totalwidth = \IEEEtotalwidth.

% minimal subnormal number

When converting form decimal to binary we use rounding with ties going
to even.

Happy IEEEing! (thanks to xint library)
}%

\newcommand\IEEEclearflags{%
}%

\makeatletter
\catcode_ 11
\def\DtoB@get@ND #1/#2[#3]{%
\edef\DtoB@s{\xintiiSgn{#1}}%
\edef\DtoB@A{\xintiiAbs{#1}}%
\def\DtoB@L{#3}%
\ifnum#3<\z@
\let\DtoB@N\DtoB@A
\edef\DtoB@D{\xintiiMul{#2}{\xintiiPow{5}{-#3}}}%
\else
\edef\DtoB@N{\xintiiMul{\DtoB@A}{\xintiiPow{5}{#3}}}%
\def\DtoB@D{#2}%
\fi
}%
\newcommand\DecimalToIEEEBinary[1]{%
\expandafter\DtoB@get@ND\romannumeral0\xintrez{#1}%
\ifnum\DtoB@s=0 \expandafter\DtoB@zero\else\expandafter\DtoB@a\fi
}%
\def\DtoB@zero{\def\IEEEresultSign{0}%
\edef\IEEEresultExponent
{\romannumeral\xintreplicate{\IEEEexponentwidth}0}%
\edef\IEEEresultMantissa
{\romannumeral\xintreplicate{\IEEEmantissawidth}0}%
}%
\def\DtoB@a{%
\edef\DtoB@S@bit{\if1\DtoB@s0\else1\fi}%
\edef\DtoB@U{\xintDecToBin{\DtoB@N}}%
\edef\DtoB@V{\xintDecToBin{\DtoB@D}}%
\edef\DtoB@Uk{\expandafter\xintLength\expandafter{\DtoB@U}}%
\edef\DtoB@Vl{\expandafter\xintLength\expandafter{\DtoB@V}}%
\ifnum\DtoB@Uk>\DtoB@Vl
% important that we are comparing here two strings of 1s and 0s of
% exact same length
\ifnum\pdfstrcmp{\DtoB@U}%
{\DtoB@V\romannumeral\xintreplicate{\DtoB@Uk-\DtoB@Vl}{0}}=\m@ne
\edef\DtoB@E{\the\numexpr\DtoB@Uk-\DtoB@Vl-\@ne+\DtoB@L}%
\else
\edef\DtoB@E{\the\numexpr\DtoB@Uk-\DtoB@Vl+\DtoB@L}%
\fi
\else
\ifnum\pdfstrcmp{\DtoB@U\romannumeral\xintreplicate{\DtoB@Vl-\DtoB@Uk}{0}}%
{\DtoB@V}=\m@ne
\edef\DtoB@E{\the\numexpr\DtoB@Uk-\DtoB@Vl-\@ne+\DtoB@L}%
\else
\edef\DtoB@E{\the\numexpr\DtoB@Uk-\DtoB@Vl+\DtoB@L}%
\fi
\fi
\ifnum\DtoB@E<\IEEEemin\space
\xint_dothis\DtoB@subnormal\fi
\ifnum\DtoB@E>\IEEEemax\space
\xint_dothis\DtoB@overflow\fi
\xint_orthat\DtoB@b
}%
\def\DtoB@subnormal{%
SORRY SUBNORMAL NUMBERS NOT YET IMPLEMENTED
\def\IEEEresultSign{0}%
\edef\IEEEresultExponent{\romannumeral\xintreplicate{\IEEEexponentwidth}0}%
\edef\IEEEresultMantissa{\romannumeral\xintreplicate{\IEEEmantissawidth}0}%
}%
\def\DtoB@b{%
\edef\DtoB@Eshifted@bits{\expandafter\@gobble
\romannumeral0\xintdectobin{\the\numexpr \DtoB@E + \IEEEebias
+ \IEEEepoweroftwo\relax}}%
\edef\DtoB@F{\the\numexpr\DtoB@E-\DtoB@L}%
\ifnum\DtoB@F>\IEEEmantissawidth % \space not really needed but let's
% terminate anyway properly the number for
% \ifnum test
\let\DtoB@f@N\DtoB@N
\edef\DtoB@f@D{\xintiiMul{\DtoB@D}{\xintiiPow{2}{\DtoB@F-\IEEEmantissawidth}}}%
\else
\edef\DtoB@f@N{\xintiiMul{\DtoB@N}{\xintiiPow{2}{\IEEEmantissawidth-\DtoB@F}}}%
\let\DtoB@f@D\DtoB@D
\fi
% xint does not provide "rounding with tie going to even"
% this is why we do some gymnastics here
% this would require xinttools, let's do without it
% \xintAssign\xintiiDivision{\DtoB@twicefplusone@N}{\DtoB@f@D}\to\DtoB@Q\DtoB@R
\edef\DtoB@temp{\xintiiDivision{\DtoB@twicefplusone@N}{\DtoB@f@D}}%
\edef\DtoB@Q{\expandafter\xint_firstoftwo\DtoB@temp}%
\edef\DtoB@R{\expandafter\xint_secondoftwo\DtoB@temp}%
\edef\DtoB@f@int{\xintHalf{\DtoB@Q}}% \xintHalf truncates
\xintiiifOdd{\DtoB@Q}%
{% f is in an [n, n+.5) interval, Q=2n+1, rounding to n needs no correction
}%
{% f is in an [n+.5,n+1) interval, tie happens iff R=0
\xintiiifZero{\DtoB@R}%
{% we are in tie case, check oddness of n+1 value
\xintiiifOdd{\DtoB@f@int}{\edef\DtoB@f@int{\xintDec{\DtoB@f@int}}}{}}%
{% we are in (n+0.5, n+1), Q = 2n+2, rounding to n+1 was ok
}%
}%
\edef\DtoB@M@bits{\expandafter\@gobble
\romannumeral0\xintdectobin{\DtoB@f@int}}%
\let\IEEEresultSign\DtoB@S@bit
\let\IEEEresultExponent\DtoB@Eshifted@bits
\let\IEEEresultMantissa\DtoB@M@bits
}%
\catcode_ 8
\makeatother

\usepackage[T1]{fontenc}
\begin{document}

\IEEEsetup{Ewidth=8, totalwidth=32}
%\IEEEprintsetup

\DecimalToIEEEBinary{-208.40625}

$-208.40625 \mapsto \IEEEresultSign|\IEEEresultExponent|\IEEEresultMantissa$

\DecimalToIEEEBinary{1/3}

$\xintSignedFrac{1/3} \mapsto \IEEEresultSign|\IEEEresultExponent|\IEEEresultMantissa$

\DecimalToIEEEBinary{1/7}

$\xintSignedFrac{1/7} \mapsto \IEEEresultSign|\IEEEresultExponent|\IEEEresultMantissa$

\DecimalToIEEEBinary{0.7}

$0.7 \mapsto \IEEEresultSign|\IEEEresultExponent|\IEEEresultMantissa$

\DecimalToIEEEBinary{355/113}

$\xintSignedFrac{355/113} \mapsto \IEEEresultSign|\IEEEresultExponent|\IEEEresultMantissa$

\DecimalToIEEEBinary{3.141592653}

$3.141592653 \mapsto \IEEEresultSign|\IEEEresultExponent|\IEEEresultMantissa$

\vspace{2\baselineskip}

\IEEEsetup{Ewidth=11, totalwidth=64}

\IEEEprintsetup

\DecimalToIEEEBinary{-208.40625}

$-208.40625 \mapsto \IEEEresultSign|\IEEEresultExponent|\IEEEresultMantissa$

\DecimalToIEEEBinary{1/3}

$\xintSignedFrac{1/3} \mapsto \IEEEresultSign|\IEEEresultExponent|\IEEEresultMantissa$

\DecimalToIEEEBinary{1/7}

$\xintSignedFrac{1/7} \mapsto \IEEEresultSign|\IEEEresultExponent|\IEEEresultMantissa$

\DecimalToIEEEBinary{0.7}

$0.7 \mapsto \IEEEresultSign|\IEEEresultExponent|\IEEEresultMantissa$

\DecimalToIEEEBinary{355/113}

$\xintSignedFrac{355/113} \mapsto \IEEEresultSign|\IEEEresultExponent|\IEEEresultMantissa$

\DecimalToIEEEBinary{3.141592653}

$3.141592653 \mapsto \IEEEresultSign|\IEEEresultExponent|\IEEEresultMantissa$

\DecimalToIEEEBinary{2.718281828}

$2.718281828 \mapsto \IEEEresultSign|\IEEEresultExponent|\IEEEresultMantissa$

\vspace{2\baselineskip}

\IEEEsetup{Ewidth=15, totalwidth=128}

\DecimalToIEEEBinary{3.141592653}

3.141592653 is represented by:

1bit for sign: \IEEEresultSign

15bits for exponent (biased) \IEEEresultExponent

112bits for mantissa (a leading 113th bit is left tacit):

\def\allowsplits #1{\ifx #1\relax \else #1\hskip 0pt plus 1pt\relax \expandafter\allowsplits\fi}%
\def\printnumber #1{\expandafter\allowsplits \romannumeral-0#1\relax }%

\noindent\printnumber\IEEEresultMantissa\relax

Here is the start of decimal expansion corresponding to this binary approximation:

\noindent\printnumber{\xinttheexpr
trunc(2+\xintBinToDec{\IEEEresultMantissa}/2^111, 60)\relax}\relax\dots

\xintDigits:=48;

The absolute error is about \xintthefloatexpr[8] 3.141592653 - 2 -
\xintBinToDec{\IEEEresultMantissa}/2^111\relax, as expected we have about 34
exact decimal digits (although here a long sequence of 9s has appeared).

\end{document}


Third version to typeset how one could possibly do it by hand.

• only conversion to 32bits illustrated here,

• subnormal numbers not handled,

• not all branches have been tested (in particular I have implemented but not tested the "tie goes to even" rule).

\documentclass[ngerman]{article}
\usepackage{xintfrac}
\usepackage{xintbinhex}
\usepackage{xinttools}
%%%%\usepackage{xintexpr}% pour un exemple
\usepackage{babel}
\usepackage[np, autolanguage]{numprint}

\makeatletter
\newcommand\TypesetIEEExxxiibitsConversion[1]{%
\edef\TCI@input{#1}%
We are going to compute the IEEE-754 32bits representation of the decimal
number $\np{\xintDecToString{\TCI@input}}_{10}$.

\expandafter\TCI@a\romannumeral0\xintrez{\TCI@input}%
}%
\def\TCI@a #1/1[#2]{%
\edef\TCI@num@s{\xintiiSgn{#1}}%
\edef\TCI@num@A{\xintiiAbs{#1}}%
\def\TCI@num@L{#2}%
\xintiiifZero\TCI@num@A
\TCI@iszero
\TCI@b
}%
\def\TCI@iszero{Well, that was easy, this number vanishes. The 32 bits of its
representation are all 0s. Done.}
\def\TCI@b{%
\ifnum\TCI@num@s>0
This number is positive, the leftmost bit is thus 0.\par
\def\TCISignBit{0}%
\else
This number is negative, the leftmost bit is thus 1.\par
\def\TCISignBit{1}%
\fi
\TCI@c
}%
\def\TCI@c{%
\edef\TCI@num@int{\xintTTrunc{\TCI@num@A/1[\TCI@num@L]}}%
\edef\TCI@num@frac
{\xintREZ{\xintSub{\TCI@num@A/1[\TCI@num@L]}{\TCI@num@int}}}%
\edef\TCI@num@int@bin{\xintDecToBin\TCI@num@int}%
The integer part is $\TCI@num@int_{10}$, whose conversion to binary is:

$\TCI@num@int@bin_2$.

\edef\TCI@num@int@bin@length{\expandafter\xintLength\expandafter
{\TCI@num@int@bin}}%
\ifnum\TCI@num@int@bin@length>24
\expandafter\TCI@A
\else
\expandafter\TCI@B
\fi
}%
\def\TCI@A{%
This occupies \TCI@num@int@bin@length\ binary digits.
We need to round to only 24 bits of precision.
\edef\TCI@bin@short{\xintKeepUnbraced{24}{\TCI@num@int@bin}}%
\edef\TCIMantissaBits{\expandafter\@gobble\TCI@bin@short}% temporary
\edef\TCI@bin@therest{\xintTrimUnbraced{24}{\TCI@num@int@bin}}%
\edef\TCI@bin@E{\the\numexpr \TCI@num@int@bin@length-1}%
The rest after the 24 leading bits $\TCI@bin@short_2$ is $\TCI@bin@therest_2$
which has $\the\numexpr\TCI@num@int@bin@length-24$ binary digit(s)%
\xintiiifZero{\TCI@num@frac}% abuse of ii usage (private note)
\TCI@Aa
\TCI@Ab
}%
\def\TCI@Aa{%
. We compare this remainder to one half of a unit in the last place i.e.
with $1\romannumeral\xintreplicate{\TCI@num@int@bin@length-25}{0}_2$.
\edef\TCI@bin@halfoneULP{\xintiiPow{2}{\TCI@num@int@bin@length-25}}%
\xintiiifCmp{\TCI@bin@therest}{\TCI@bin@halfoneULP}
\TCI@Aaa
\TCI@Aab
{It is greater so \TCI@roundup}
}%
\def\TCI@Aaa{%
There is strictly less than half a u.l.p. (unit in the last place) left, so this
is it.
\TCI@finish
}%
\def\TCI@Aab{%
We are in a tie situation. We must round to even.
\xintiiifOdd{\TCI@bin@short}%
\TCI@Aaba
\TCI@Aabb
}%
\def\TCI@Aaba{%
\edef\TCIMantissaBits
{\expandafter\@gobble\romannumeral0%
\xintdectobin{\xintInc{\xintBinToDec{\TCI@bin@short}}}}%
This means here that we must increase by one from $\TCI@bin@short$
to $1\TCIMantissaBits_2$.

The exponent is $e = \TCI@bin@E$.
\xintiiifZero{\xintiNum{\TCIMantissaBits}}
\TCI@roundingupwenttopoweroftwo
\TCI@finish
}%
\def\TCI@Aabb{%
Our leading bits already correspond to an even number, so this is it.
\TCI@finish
}%
\def\TCI@Ab{ (and there is also fractional part
$\np{\xintDecToString{\TCI@num@frac}}_{10}$). We compare this remainder to
one half of a unit in the last place i.e. with
$1\romannumeral\xintreplicate{\TCI@num@int@bin@length-25}{0}_2 =2^{\the\numexpr\TCI@num@int@bin@length-25}$.
\edef\TCI@bin@halfoneULP{\xintiiPow{2}{\TCI@num@int@bin@length-25}}%
\xintiiifCmp{\TCI@bin@therest}{\TCI@bin@halfoneULP} \TCI@Aba \TCI@Abb
\TCI@Abc
}%
\def\TCI@Aba{%
It is less (and the fractional part can not change that), so this is it.
\TCI@finish
}%
\def\TCI@Abb{%
The integer remainder is exactly one half of a ULP but there is still a
\emph{non-vanishing fractional part}. Thus, \TCI@roundup
}%
\def\TCI@Abc{%
We have more than one half of a u.l.p. Hence, \TCI@roundup }%
\def\TCI@B{%
\xintiiifZero\TCI@num@int \TCI@Bloop \TCI@C
}%
\def\TCI@Bloop{%
The integral part vanishes. We multiply by 2 the input as many times as is
needed to obtain a non-vanishing integral part, i.e. the input will now
become a decimal number at least $1$ and less than $2$. I.e. we must multiply
$\TCI@num@A$ by $2$ enough times for it to become at least equal to
$10^{\the\numexpr-\TCI@num@L}$.

\def\TCI@bin@E{0}
\xintloop
\edef\TCI@num@A{\xintDouble{\TCI@num@A}}%
\edef\TCI@bin@E{\the\numexpr\TCI@bin@E-1}%
\unless
\ifnum-\TCI@num@L<\expandafter\xintLength\expandafter{\TCI@num@A}\space
\repeat

It turns out we had to do this $\the\numexpr-\TCI@bin@E$ times, and we are
now looking at:

$\np{\xintDecToString{\TCI@num@A/1[\TCI@num@L]}}_{10}$.

The exponent will thus be $\TCI@bin@E$ (or exceptionally one more if we are
very close to $2$ here, you can probably tell better than me because I am
too lazy to check immediately at this stage).

\edef\TCI@poweroftwo{\xintiiPow{2}{24}}%
\def\TCI@num@int@bin@length{25}%
We now multiply our (already multiplied) input by $2^{24}=\TCI@poweroftwo$,
in order for the integral part to occupy exactly 25 binary digits (we will
use the last one to decide in which direction goes the rounding to nearest
binary float).

\edef\TCI@num@A{\xintiiMul{\TCI@poweroftwo}{\TCI@num@A}}%
Our modified input is $\np{\xintDecToString{\TCI@num@A/1[\TCI@num@L]}}_{10}$\par
\TCI@D
}%
\def\TCI@C{%
This occupies \TCI@num@int@bin@length\ binary digit(s).
\edef\TCI@poweroftwo{\xintiiPow{2}{25-\TCI@num@int@bin@length}}%
\edef\TCI@Eshift{\the\numexpr25-\TCI@num@int@bin@length}%
\edef\TCI@bin@E{\the\numexpr24-\TCI@Eshift}%
\def\TCI@num@int@bin@length{25}%
In order to work mainly with integers, we first multiply our input by
$2^{\TCI@Eshift}=\TCI@poweroftwo$, then the integral part will occupy
25 binary digits (we will use the last one to decide the rounding to
nearest binary float). The final exponent will be
$\TCI@bin@E$, or perhaps one unit more if some rounding to next
power of two is needed.

\edef\TCI@num@A{\xintiiMul{\TCI@poweroftwo}{\TCI@num@A}}%
Our modified input is $\np{\xintDecToString{\TCI@num@A/1[\TCI@num@L]}}_{10}$\par
\TCI@D
}
\def\TCI@D{%
\edef\TCI@num@int{\xintTTrunc{\TCI@num@A/1[\TCI@num@L]}}%
\edef\TCI@num@frac
{\xintREZ{\xintSub{\TCI@num@A/1[\TCI@num@L]}{\TCI@num@int}}}%
\edef\TCI@num@int@bin{\xintDecToBin\TCI@num@int}%

The integer part in binary is $\TCI@num@int@bin_2$ and occupies as expected
25 bits.

\def\TCI@num@int@bin@length{25}%
We need to round to only 24 bits of precision.
\edef\TCI@bin@short{\xintKeepUnbraced{24}{\TCI@num@int@bin}}%
\edef\TCIMantissaBits{\expandafter\@gobble\TCI@bin@short}% temporary
\edef\TCI@bin@therest{\expandafter\xintLastItem\expandafter{\TCI@num@int@bin}}%
The 25th bit is $\TCI@bin@therest_2$%
\xintiiifZero{\TCI@num@frac}% abuse of ii usage (private note)
\TCI@Aa
\TCI@Ab
}%
\def\TCI@roundup{%
we must increase the mantissa by one unit in the last place, obtaining
\edef\TCIMantissaBits
{\expandafter\@gobble\romannumeral0%
\xintdectobin{\xintInc{\xintBinToDec{\TCI@bin@short}}}}%
$1\TCIMantissaBits_2$.
The exponent is $e = \TCI@bin@E$.
\xintiiifZero{\xintiNum{\TCIMantissaBits}}
\TCI@roundingupwenttopoweroftwo
\TCI@finish
}%
\def\TCI@roundingupwenttopoweroftwo{%
Attention that the rounding went to a power of two, so we must increase
it by $1$. The mantissa will be with 23 zeros (because the leading
bit is tacit).

\edef\TCI@bin@E{\the\numexpr\TCI@bin@E+1}%
\edef\TCIMantissaBits{\romannumeral\xintreplicate{23}{0}}%
\TCI@finish
}%
\def\TCI@finish{\par
The stored (biased) exponent will be $\TCI@bin@E + 127 = \the\numexpr\TCI@bin@E + 127\relax$  which in binary
gives
\edef\TCIExponentBits{\expandafter\@gobble\romannumeral0%
\xintdectobin{\the\numexpr\TCI@bin@E + 127 +
256\relax}}%
$\TCIExponentBits$.

In total: $\TCISignBit|\TCIExponentBits|\TCIMantissaBits$.\par
}%
\makeatother

\usepackage[T1]{fontenc}
\begin{document}

\TypesetIEEExxxiibitsConversion{0.000000000123}
%
% 0|01011110|00001110011110101101100
% 0 01011110 00001110011110101101100

\clearpage
\TypesetIEEExxxiibitsConversion{-0.0000000001234567}
% 1|01011110|00001111011110111111001
% 1 01011110 00001111011110111111001

\clearpage
\TypesetIEEExxxiibitsConversion{-1234.567}
% 1|10001001|00110100101001000100101
% 1 10001001 00110100101001000100101

\clearpage
\TypesetIEEExxxiibitsConversion{-0.00000000000000001234567}
% 1|01000110|11000111011110011000111
% 1 01000110 11000111011110011000111

\clearpage
% hmm pénible l'input car \np ne veut pas de /, donc \xintDecToString
% doit être utilisé uniquement avec /1
% 2^24-0.5
% 1 - 2^{-25}
% (2^{25}-1)/2^{25}
% (2^{25}-1)*5^{25}/10^{25}
\TypesetIEEExxxiibitsConversion
{\xintiiMul{\xintDec{\xintiiPow{2}{25}}}{\xintiiPow{5}{25}}[-25]}

\clearpage

%  8388608 = 2**23
% 16777216 = 2**24
% 12345678 - 0.5
% 12345677.5
% 12345677.5/1024
% 12345677.5*5**10/10**10
% \typeout{\xintDecToString{\xinttheexpr 12345677.5*5**10[-10]\relax}}
% 12056.32568359375
\TypesetIEEExxxiibitsConversion{12056.32568359375}
% 0|10001100|01111000110000101001110
% 0 10001100 01111000110000101001110

\clearpage

%\typeout{\xintDecToString{\xinttheexpr 12345676.5*5**12[-12]\relax}}
% 12056.32568359375
\TypesetIEEExxxiibitsConversion{3014.0811767578125}%
% 0|10001010|01111000110000101001100
% 0 10001010 01111000110000101001101

\end{document}


• Hi,thanks for that. But I do I have to take an exam where I may have to do this on my own. So I appreciate some practice. ;) Very impressive though, LaTex doesn't stop to amaze me. Commented Nov 29, 2018 at 11:46
• I can add a version which does it step by step in a way one could do it by hand, and prints out the steps so that you have some practice sheets with correction... this could serve as practice for your example, but of course for this I would need to know what is expected method... (I assume conversion to binary of integers is "pre-requisite" and perhaps you need to explain how to get "fractional binary digits" and once you get enough you can write in IEEE format?)
– user4686
Commented Nov 29, 2018 at 13:15
• I have added such a way. They are probably as many ways as computer science courses, else the world would be boring isn't it?
– user4686
Commented Nov 29, 2018 at 16:35
• important to notice: the third version make absolutely no check on exponent being in allowed range for IEEE 32bits... you will have been warned... and subnormal numbers are not handled (this corresponds to underflow of exponent...)
– user4686
Commented Nov 29, 2018 at 17:48