Como posso ilustrar o número decimal em conversão binária

Como posso ilustrar o número decimal em conversão binária

Gostaria de converter o número decimal em binário, conforme feito pelo comando \baseexpansionna resposta do jfbu à pergunta:

Como posso ilustrar a conversão de decimal para binário?

Por exemplo, gostaria de converter números como 0.4075 em base bou como 0.A46C em base 10. Infelizmente, não sei programá-lo em LaTeX.

Alguém conseguiu? Xavier.

Para mais precisão: gostaria do esquema mental:tabela de imagem

e quero interrompê-lo após p iterações, se necessário: insira a descrição da imagem aqui

Se você tiver um algoritmo melhor para ser mostrado no LaTeX, ficarei muito feliz.

Obrigado! Você fez um ótimo trabalho!

Por fim, posso fazer a mesma coisa para qualquer base de 2 a 36, ​​e o resultado escrito com letras como na imagem abaixo? final

Responder1

Você não pode converter de decimal para binário exatamente porque 1/5 precisa de infinitos coeficientes. (no entanto, podemos escrever código para obter a expansão periódica)

Ao passar de hexadecimal para decimal, isso está disponível em formato xintexpr.

Mas como o resultado usará xintfracnotação interna, também pego uma \PolDecToStringmacro em polexpr 0.4. (muito recente, talvez seja necessário atualizar sua instalação do TeX).

\documentclass{article}
\usepackage{xintexpr}
\usepackage{xintbinhex}

\usepackage{polexpr}[2018/02/16]% Only for its \PolDecToString commodity!
\begin{document}
\PolDecToString{\xintREZ{\xinttheexpr "0.A46C\relax}}
\end{document}

insira a descrição da imagem aqui


Aqui está a conversão de binário para decimal

\documentclass{article}
\usepackage{xintexpr}% we could load xintfrac only, but anyhow
% polexpr loads xintexpr
\usepackage{xintbinhex}

\usepackage{polexpr}[2018/02/16]% Only for its \PolDecToString commodity!

\makeatletter
\newcommand\FracBinToDecimal[1]{\romannumeral-`0%
  % to be used on input expanding to
  % <binary digits>[.<binary digits>]
  \expandafter\FracBin@ToDecimal\romannumeral0\xintraw{#1}%
  % the above handles this abusively as if was a decimal number with
  % only 1's and 0's
}%
\def\FracBin@ToDecimal #1/#2[#3]{% something got wrong if #2 is not 1 !
  \ifnum#3<\z@
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
  {\PolDecToString
     {\xintREZ{\xintiiMul{\xintBinToDec{#1}}{\xintiiPow{5}{-#3}}[#3]}}%
  }%
  {\xintiiMul{\xintBinToDec{#1}}{\xintiiPow{2}{#3}}}%
}%
\makeatother

\newcommand\test[1]{\[#1_b = \FracBinToDecimal{#1}_{10}\]}

\begin{document}    
\test{11001}

\test{11001.11001}

\test{0.0001}

\test{-1111.1111}
\end{document}

insira a descrição da imagem aqui


Após adição de planilhas ao OP, mostrando o design procurado.

Observe que, sendo todos os cálculos exatos, não pode haver erros, como são aparentes nas planilhas do OP.

Poderia ser possível adicionar um detector de período, mas a memória de todas as partes fracionárias anteriores deve ser mantida (se torna um problema se você tiver um período com duração da ordem de 1.000.000, por exemplo). Geralmente o período começa imediatamente após a casa decimal e podemos detectar quando começa mais tarde. No entanto, é verdade que o período pode ser extremamente grande:

Considere o exemplo 0.521728515624básico 16. 1000000000000=10^12são 16^3vezes 5^12. Portanto teremos um ponto final que (salvo coincidência numérica milagrosa) começará 3 dígitos após a casa decimal. A duração do período (o numerador aqui é primo de 5) será da ordem de 16no grupo multiplicativo de Z/5^12 Z.

phi(5^12) = 5^12 - 5^11 = 4 * 5^11 = 195312500

Então

>>> for i in [2, 4, 5]:
...     pow(16, 195312500//i, 244140625)
... 
1
1
97656251

prova que isso 16é exatamente de ordem 5^11 = 48828125neste grupo multiplicativo. Portanto, esta é a duração do período da expansão de base 16 de 0.521728515624: o padrão periódico tem 48828125dígitos!

Em geral, vemos que encontrar a duração do período a priori está muito relacionado à fatoração de números. Todos os cálculos acima poderiam ter sido feitos rapidamente por um programa xintexpr adequado, porque os fatores primos são (muito) pequenos. Quando começamos a ter fatores primos com mais de 8 dígitos, isso se torna um desafio difícil para cálculos usando apenas expansão macro TeX!

Eu não usei tabular para permitir quebra de página, o melhor seria usar algum TeX, \halignvocê também pode usar talvez o ambiente de tabulação do LaTeX (nunca testado). Ou simplesmente caixas de larguras fixas.

\documentclass[french]{article}
\usepackage{xintfrac, xinttools}
\usepackage{polexpr}[2018/02/16]% Pour \PolDecToString
\usepackage{babel}
\usepackage[autolanguage,np]{numprint}
\usepackage{amsmath}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\newcommand\ConvertitEnHexa[2][25]{% #1 MUST BE OF THE 0.<decimal digits> type
  % (we can not use 1/5 because numprint's \np macro does not like the /)
  % the dot will be converted into a comma by \np macro
  % computes 25 digits by default. Abort earlier if all become zeros.
  \noindent Nombre à convertir en base 16: \np{#2}.\par
  \edef\ConvertitNombre{\xintRaw{#2}}%
  \xintiloop[1+1]
  \edef\ConvertitSeizeFoisNombre{\xintMul{16}{\ConvertitNombre}}%
  \edef\ConvertitSeizeFoisNombrePartieInt
      {\xintTTrunc{\ConvertitSeizeFoisNombre}}%
  \edef\ConvertitSeizeFoisNombrePartieFrac
      {\xintTFrac{\ConvertitSeizeFoisNombre}}%
  $16\times\np{\PolDecToString{\ConvertitNombre}}
             = \boxed{\ConvertitSeizeFoisNombrePartieInt} +
               \np{\PolDecToString{\ConvertitSeizeFoisNombrePartieFrac}}$\par
  \let\ConvertitNombre\ConvertitSeizeFoisNombrePartieFrac
  \xintifZero{\ConvertitNombre}{\xintbreakiloop}{}%
  \ifnum#1>\xintiloopindex\space
  \repeat
}
\newcommand\ConvertitFracEnHexa[2][25]{%
  % #1 MUST BE OR EXPAND TO A/B WITH 0 < A < B
  % computes 25 digits by default. Abort earlier if all become zeros.
  \edef\ConvertitNombre{\xintIrr{#2}}%
  \noindent Nombre à convertir en base 16: \ConvertitNombre.\par
  \xintiloop[1+1]
  \edef\ConvertitSeizeFoisNombre{\xintMul{16}{\ConvertitNombre}}%
  \edef\ConvertitSeizeFoisNombrePartieInt
      {\xintTTrunc{\ConvertitSeizeFoisNombre}}%
  \edef\ConvertitSeizeFoisNombrePartieFrac
      {\xintTFrac{\ConvertitSeizeFoisNombre}}%
  $16\times\xintFrac{\xintRawWithZeros\ConvertitNombre}
             = \boxed{\ConvertitSeizeFoisNombrePartieInt} +
               \xintFrac{\xintRawWithZeros\ConvertitSeizeFoisNombrePartieFrac}$\par
  \let\ConvertitNombre\ConvertitSeizeFoisNombrePartieFrac
  \xintifZero{\ConvertitNombre}{\xintbreakiloop}{}%
  \ifnum#1>\xintiloopindex\space
  \repeat
}

\begin{document}
\ConvertitEnHexa{0.99609375}

\bigskip

\ConvertitEnHexa{0.521728515625}
\bigskip

\ConvertitEnHexa{0.521728515624}
et ça peut continuer longtemps avant que l'on voie la période\dots\bigskip

\clearpage
\ConvertitEnHexa[12]{0.4075}
etc\dots

\bigskip

\ConvertitFracEnHexa[12]{4095/4096}

\bigskip

\ConvertitFracEnHexa[7]{1/5}
etc\dots

\bigskip

\ConvertitFracEnHexa[7]{3/7}
etc\dots

\bigskip

\clearpage

\ConvertitFracEnHexa[7]{9/11}
etc\dots

\end{document}

Última atualização. Imagens atualizadas para corresponder a isso.

\documentclass[french]{article}
\usepackage{xintfrac, xinttools}
\usepackage{polexpr}[2018/02/16]% Pour \PolDecToString
\usepackage{babel}
\usepackage[autolanguage,np]{numprint}
\usepackage{amsmath}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}

\newcommand\MiniConvert[1]{\ifcase #1
  0\or 1\or 2\or 3\or 4\or 5\or 6\or 7\or 8\or 9\or A\or B\or C\or D\or E\or
  F\or G\or H\or I\or J\or K\or L\or M\or N\or O\or P\or Q\or R\or S\or T\or
  U\or V\or W\or X\or Y\or Z\else\ERROR\fi}%
\newcommand\ConvertitEnBaseB[3][25]{% #1 MUST BE OF THE 0.<decimal digits> type
  % (we can not use 1/5 because numprint's \np macro does not like the /)
  % the dot will be converted into a comma by \np macro
  % computes 25 digits by default. Abort earlier if all become zeros.
  % #3 = base < 36
     \def\ConvertiDots{\dots}%
  \noindent Nombre à convertir en base #3: \np{#2}.\par
  \def\Converti{0,}%<<<< LOCALIZE TO YOUR LANGUAGE
  \edef\ConvertitNombre{\xintRaw{#2}}%
  \xintiloop[1+1]
  \edef\ConvertitBFoisNombre{\xintMul{#3}{\ConvertitNombre}}%
  \edef\ConvertitBFoisNombrePartieInt
      {\xintTTrunc{\ConvertitBFoisNombre}}%
  \edef\ConvertitBFoisNombrePartieFrac
      {\xintTFrac{\ConvertitBFoisNombre}}%
  $#3\times\np{\PolDecToString{\ConvertitNombre}}
             = \boxed{\ConvertitBFoisNombrePartieInt} +
               \np{\PolDecToString{\ConvertitBFoisNombrePartieFrac}}$
  \hfill
  \llap{${}\longrightarrow{}$\MiniConvert\ConvertitBFoisNombrePartieInt}\par
  \edef\Converti{\Converti\MiniConvert{\ConvertitBFoisNombrePartieInt}}%
  \let\ConvertitNombre\ConvertitBFoisNombrePartieFrac
  \xintifZero{\ConvertitNombre}
    {\xintbreakiloopanddo\let\ConvertiDots\empty.}%
    {}%
  \ifnum#1>\xintiloopindex\space
  \repeat
  \noindent\mbox{}\hfill$\np{#2}=[$\Converti\ConvertiDots$]_{#3}$\par
}
\newcommand\ConvertitFracEnBaseB[3][25]{%
  % #1 MUST BE OR EXPAND TO A/B WITH 0 < A < B
  % computes 25 digits by default. Abort earlier if all become zeros.
     \def\ConvertiDots{\dots}%
  \edef\ConvertitNombre{\xintIrr{#2}}%
  \def\Converti{0,}%<<<< LOCALIZE TO YOUR LANGUAGE
  \noindent Nombre à convertir en base #3: \ConvertitNombre.\par
  \xintiloop[1+1]
  \edef\ConvertitBFoisNombre{\xintMul{#3}{\ConvertitNombre}}%
  \edef\ConvertitBFoisNombrePartieInt
      {\xintTTrunc{\ConvertitBFoisNombre}}%
  \edef\ConvertitBFoisNombrePartieFrac
      {\xintTFrac{\ConvertitBFoisNombre}}% does \xintREZ, not good for us
  $#3\times\xintFrac{\xintRawWithZeros\ConvertitNombre}
             = \boxed{\ConvertitBFoisNombrePartieInt} +
               \xintFrac{\xintRawWithZeros\ConvertitBFoisNombrePartieFrac}$\par
  \hfill
  \llap{${}\longrightarrow{}$\MiniConvert\ConvertitBFoisNombrePartieInt}\par
  \edef\Converti{\Converti\MiniConvert{\ConvertitBFoisNombrePartieInt}}%
  \let\ConvertitNombre\ConvertitBFoisNombrePartieFrac
  \xintifZero{\ConvertitNombre}
    {\xintbreakiloopanddo\let\ConvertiDots\empty.}%
    {}%
  \ifnum#1>\xintiloopindex\space
  \repeat
  \noindent\mbox{}\hfill$\xintFrac{#2}=[$\Converti\ConvertiDots$]_{#3}$\par}%


\begin{document}
\ConvertitEnBaseB{0.99609375}{16}

\bigskip

\ConvertitEnBaseB{0.521728515625}{16}
\bigskip

\ConvertitEnBaseB{0.521728515624}{16}
et ça peut continuer longtemps avant que l'on voie la période\dots\bigskip

\ConvertitEnBaseB[12]{0.4075}{16}
etc\dots

\bigskip

\ConvertitFracEnBaseB[12]{4095/4096}{16}

\bigskip

\ConvertitFracEnBaseB[7]{1/5}{16}
etc\dots

\bigskip

\ConvertitFracEnBaseB[7]{3/7}{16}
etc\dots

\bigskip

\ConvertitFracEnBaseB[10]{9/11}{16}
etc\dots

\bigskip

\ConvertitFracEnBaseB[10]{9/11}{15}
etc\dots

\bigskip

\ConvertitFracEnBaseB[10]{9/11}{14}
etc\dots

\bigskip

\ConvertitFracEnBaseB[15]{9/11}{13}
etc\dots

\bigskip

\ConvertitFracEnBaseB[10]{9/11}{36}
etc\dots

\bigskip

\ConvertitFracEnBaseB[15]{9/11}{2}
etc\dots
\end{document}

insira a descrição da imagem aqui

insira a descrição da imagem aqui

insira a descrição da imagem aqui

insira a descrição da imagem aqui

insira a descrição da imagem aqui

insira a descrição da imagem aqui

informação relacionada