Saltar al contenido

Crear figuras para mostrar valores binarios

Hola usuario de nuestro sitio web, hemos encontrado la solución a lo que andabas buscando, has scroll y la encontrarás más abajo.

Solución:

editar (2017) de la segunda mitad de la respuesta: desde octubre de 2014, esta parte de la respuesta se rompió debido a una redefinición en xint 1.1 de xintFloor cuyo significado original, como se usa aquí, ahora está en una macro llamada xintiFloor. También comportamiento de xintFloat cambió un poco en xint 1.2k (2017/01/06) para el caso de redondeo a una potencia de diez, la imagen de salida tuvo que actualizarse.

De hecho, se puede definir un comando y automatizar un poco.

bits binarios

documentclassarticle

usepackagexinttools

newcounterbitindex

newcommandbitpicture [3]%
  setlengthunitlength1mm
  setlengthfboxsep0mm
  beginpicture(130,16)
    % sign bit
  put(2,4)framebox(4,8)#1
  % exponent
  setcounterbitindex1%
  xintFor* ##1 in #2
  do
  put(numexpr 2+4*valuebitindex,4)framebox(4,8)##1%
   stepcounterbitindex%
  % fraction
  setcounterbitindex1%
  xintFor* ##1 in #3
  do
  put(numexpr 34+4*valuebitindex,4)framebox(4,8)##1%
   stepcounterbitindex%
  % upper labels
  put(0,14)scriptsizeMSB
  put(126,14)scriptsizeLSB
  %lower labels
  put(3,0)scriptsizeS
  put(7,0)line(0,1)2
  put(7,1)vector(1,0)8
  put(16,0)scriptsizeExponent
  put(37,1)vector(-1,0)8
  put(37,0)line(0,1)2
  put(39,0)line(0,1)2
  put(39,1)vector(1,0)38
  put(79,0)scriptsizeFraction
  put(130,1)vector(-1,0)38
  put(130,0)line(0,1)2
endpicture%


begindocument
beginfigure
centering
bitpicture 01000000010010010000111111010000
captionThe value 3.14159 stored as a textttfloat.
labelfigure:pi_example
endfigure 
enddocument

Además, podría ser posible calcular la representación binaria a partir de la decimal (si alguien me explica la regla, puedo implementarla).


Como complemento, aquí hay un código para convertir en Double Binary (ver wikipedia). Al ingresar cualquier cosa aceptable por las macros de xintfrac, al generar el formato binario doble en 64 bits, en tres macros BDsign, BDexponent, BDfraction. Como la entrada puede tener cientos de dígitos, primero se convierte en un decimal flotante con 24 precisión de dígitos. La conversión a doble binario se realiza desde ese punto de partida con 24 dígitos decimales y una potencia de diez exponente (observe que xint permite todo el camino hasta 10^2147483647, así el código trata NaN y también se ocupa de los números por debajo de lo normal). También hay una macro que va en sentido inverso.

Naturalmente, esto solo ilustra la conversión implementada aquí, conversión cuyos pasos se explican en los comentarios del código.

los bitpicture del código anterior podría rehacerse para el 64 caso de bits, solo es necesario cambiar algunas cosas y bitpictureBDsignBDexponentBDfraction trabajaría. Pero aquí elegí una representación en línea más simple.

documentclassarticle
usepackagexintfrac
usepackagexintbinhex
usepackagexintexpr
usepackagecolor
usepackage[paperheight=50cm,vscale=0.9,hscale=0.72]geometry

makeatletter
newcommandToDouble[1]%
% This commands handles arbitrary expandable material producing 
   % an input number in the formats as understood by xint: integers,
   % fractions, decimal numbers, scientific notation, or fractions with such
   % numbers etc... for example 12.34, or 1.07/3.25 or 12e7, or
   % 1.25e7/3.12e5
% It computes the Double Precision Binary representation and puts the
% 64 binary digits in the three macros BDsign (1bit), BDexponent
% (11bit), BDfraction (52bit)
   edef[email protected]
#1% % Then we convert #1 to float with 24 digits of precision, this step % is in case % we have some very long input like pi with 1000 digits for example. % We don't want to have to do computations with that many digits % aftewards. % (oodef = def with twice expansion of the contents) % 24 digits is overkill. oodef[email protected] xintFloat [24][email protected]% xintifSgn [email protected] defBDsign 1oodef[email protected] xintAbs [email protected][email protected] defBDsign 0defBDexponent00000000000% defBDfraction0000000000000000000000000000000000000000000000000000 defBDsign 0[email protected] % % def[email protected]@t #1[#2]def[email protected] #2% def[email protected] % % first we get the power of 10 such that 10^t <= x < 10^t+1 % this is done by converting to float with 1 digit of precision. % XINTinFloat will produce d[t], with 1<= d <= 10 (10 is obtained % only from upper rounding, for example 9.95 becomes 10[0]) % Note that t may be as big as 2147483647 which is way beyond % what can be represented as a double oodef[email protected] XINTinFloat [1][email protected]% expandafter[email protected]@t[email protected] % What we really want is exponent of a power of two which is about % 3.32 times t: % 1/log10(2) = 3.3219280948873623478703194294... % we don't need that much precision as allowable range of decimal exponents % (single precision) from -38 to +38 for normal and -45 to -38 for % subnormal numbers % (double precision) from -324 to +308 % we thus take a lower bound, and then multiply by 2 or divide by 2 the % number of times (3 or perhaps 4 times at most) to end up in the correct % range 1<= f <2. We will then need to check for subnormal numbers. % to reduce overhead in handling of y, we first check the size of t: xintifGt [email protected]1000 % too big number (10^1000) defBDexponent 11111111111% defBDfraction 1000000000000000000000000000000000000000000000000000% [email protected] % xintifLt [email protected]-1000 % too close to zero number (10^-1000) defBDexponent 00000000000% defBDfraction 0000000000000000000000000000000000000000000000000000% [email protected] % % we are now guaranteed that [email protected] will be usable with numexpr, % let's get it: % (since 1.1 we need to use xintiFloor to get an integer, % as xintFloor adds a trailing /1[0] for better efficiency % in chaining xintfrac.sty macros) oodef[email protected] xintiFloor xintMul 3.321928[email protected]% % below apart from the float computation of the power of 2, % the other operations are handled exactly % (xintDiv does not do much as xint handles fractions natively, % it just prepares a fraction) % (the real work will be done by the comparison tests) oodef[email protected] xintDiv [email protected]xintFloatPow [24]2[email protected]% % xintloop xintifLt [email protected]1 oodef[email protected] xintMul 2[email protected]% odef[email protected] thenumexpr [email protected]% iftrue % iffalse % stop the loop if z >= 1 repeat % xintloop xintifLt [email protected]2 iffalse % stop the loop if z < 2 oodef[email protected] xintDiv [email protected]2% odef[email protected] thenumexpr [email protected]+1% iftrue % repeat % odef [email protected] thenumexpr 1023+[email protected] % biased exponent % We need to check if we have a sub-normal number or NaN ifnum [email protected] > 2046 % beyond allowable range of double precision defBDexponent 11111111111% defBDfraction 1000000000000000000000000000000000000000000000000000% else ifnum [email protected] < 1 % sub-normal number % x is theoretically less than 2^-1022 % however with the computations giving the z such that 1<= z < 2 % z is only an approximation to x 2^(-y) % Thus it could be that the x is in fact 2^-1022 or slightly % greater and should then be represented as a normal number % we forget about the computed z and work again starting from x % We multiply x by 2^1022+52=2^1074 % 2^1074=2.024022533073106183524953467.. 10^323 % keep it with 24 digits precision -> 202402253307310618352495[300] % then we round to the nearest integer and % later we test to check if we have something too big oodef[email protected] xintiRound0 xintMul [email protected]202402253307310618352495[300]% % xintifGt[email protected]4503599627370495 % 2^52= 4503599627370496 % we have in fact a normal number between 2^-1022 and 2^-1021 defBDexponent 00000000001% oodef[email protected] xintDecToBin [email protected]% % we gobble the first 1 of the 53bit representation to get 52 bits. oodefBDfraction expandafter@gobble[email protected] % % % we really have a sub-normal number defBDexponent 00000000000% % we add 2^52, convert to binary, gobble the first 1. oodef[email protected] xintDecToBin xintiiAdd 4503599627370496[email protected]% oodefBDfraction expandafter@gobble[email protected] % % else % 1<= e <= 2046: normal case % 1<= z < 2 holds for the fraction part. % We multiply by 2^52= 4503599627370496, % round, convert to binary, and gobble the first 1. % However rounding may have been up to 2^53, thus we test for % that case and then use rather 2^53-1. % oodef [email protected] xintiRound0 xintMul 4503599627370496[email protected]% % xintifEq [email protected]9007199254740992 defBDfraction 1111111111111111111111111111111111111111111111111111% % convert to binary and gobble the first 1 of the 53bit % representation oodef[email protected] xintDecToBin [email protected]% oodefBDfraction expandafter@gobble[email protected] % % end of BDfraction computation % we also need the biased exponent in 11bit binary % oodef [email protected] xintDecToBin thenumexpr 2048+[email protected]relax% oodef BDexponent expandafter@gobble[email protected] % fi fi relax % def[email protected] #1relax % the decimal float evaluation will be made with current value of % xintDigits, and printed according to the optional parameter newcommandPrintAsDecimalFloat [4][16]% edef[email protected]#2% edef[email protected]#3% edef[email protected]#4% if1[email protected]fi def[email protected]11111111111% ifx[email protected][email protected] xintifZero [email protected]inftyNaN% else def[email protected]00000000000% ifx[email protected][email protected] xintFloat [#1] xintthefloatexpr 2^(-1074)*xintBinToDec[email protected]relax% else % inserts a leading 1 odef[email protected] expandafter1[email protected]% xintFloat [#1] xintthefloatexpr 2^(xintBinToDec[email protected])* (xintBinToDec[email protected]/2^52)relax% fi fi makeatother newcommandPrintCurrentDouble BDsign xintifZeroBDexponenttextcolorred xintifEqBDexponent11111111111textcolorredtextcolorblue% BDexponent% BDfraction newcommandCurrentDoubleAsDecimalFloat xintDigits:=18;PrintAsDecimalFloatBDsignBDexponentBDfraction newcommandTest [1]textttdetokenize#1 (xintFloat [16]#1)newlineToDouble#1 PrintCurrentDouble $to$CurrentDoubleAsDecimalFloat par begindocument First line of each paragraph shows the number as input to the conversion routine, then within parentheses its conversion to a decimal floating number with 16 digits of precision, then on the next line the 64bit double representation and next the reconstructed number as a floating decimal evaluated with 18 digits of precision and printed with 16. % This comment of original answer is false since xint 1.2k (2017/01/06): % %% Notice that verb|xintFloat| outputs verb|10.000..00eN| when % %% the rounding went up. % Policy was modified at xint 1.2k and output always has total of P digits % with P the floating point precision: so 1.00..., not 10.00... Test3.14159 Test-3.14159 Test3.14159265 Test3.141592653590 Test3.14159265358979324 Test1[-20] Test1[-200] Test1.2345678987654321e-304 Test1.2345678987654321e-312 Test1.2345678987654321e-320 Test1[-400] Test-1[-2000] Test1[20] Test1[200] Test1[400] Test1[2000] Testxinttheiexpr 2^50relax Testxinttheiexpr 2^100relax Testxinttheiexpr 2^150relax Testxinttheiexpr 2^200relax Test1234/4567 We also obtain, computing with 18 decimal digits and printing 17: xintDigits := 18; begintabularrl minimal subnormal double& PrintAsDecimalFloat [17] 0000000000000000000000000000000000000000000000000000000000000001\ maximal subnormal double& PrintAsDecimalFloat [17] 0000000000001111111111111111111111111111111111111111111111111111\ minimal normal double& PrintAsDecimalFloat [17] 0000000000010000000000000000000000000000000000000000000000000000\ maximal normal double& PrintAsDecimalFloat [17] 0111111111101111111111111111111111111111111111111111111111111111\ endtabular enddocument

ingrese la descripción de la imagen aquí

En caso de que no lo sepa, el paquete de campo de bytes se puede utilizar para escribir valores binarios. Su objetivo principal es dibujar campos de datos de protocolo, pero se puede utilizar para cualquier tipo de campo de datos.

Simplemente escribe lo que quieras, pero no puedes usarlo para convertir de binario a decimal como propone jbfu con su gran paquete xint.

Un pequeño ejemplo con bytefield

documentclassarticle
usepackagebytefield
usepackagexcolor
usepackagegraphicx

newcommandcolorbitbox[3]%
rlapbitbox#2color#1rulewidthheight%
bitbox#2#3
definecolorlightcyanrgb0.84,1,1
definecolorlightgreenrgb0.64,1,0.71
definecolorlightredrgb1,0.7,0.71

begindocument

textttbytefield package helps you to draw data fields.

begincenter
beginbytefield[bitheight=widthof~Sign~,
boxformatting=centeringsmall]32
bitheader[endianness=big]31,23,0 \
colorbitboxlightcyan1rotatebox90Sign &
colorbitboxlightgreen8Exponent &
colorbitboxlightred23Mantissa
endbytefield
endcenter

You can also fill specify every bit

begincenter
beginbytefield[bitheight=widthof~Sign~,
boxformatting=centeringsmall]32
bitheader[endianness=big]31,23,0 \
colorbitboxlightcyan10 &
colorbitboxlightgreen11 &
colorbitboxlightgreen10 &
colorbitboxlightgreen10 &
colorbitboxlightgreen10 &
colorbitboxlightgreen10 &
colorbitboxlightgreen10 &
colorbitboxlightgreen10 &
colorbitboxlightgreen10 &
colorbitboxlightred11 &
colorbitboxlightred11 &
colorbitboxlightred11 &
colorbitboxlightred11 &
colorbitboxlightred10 &
colorbitboxlightred10 &
colorbitboxlightred10 &
colorbitboxlightred10 &
colorbitboxlightred10 &
colorbitboxlightred10 &
colorbitboxlightred10 &
colorbitboxlightred10 &
colorbitboxlightred10 &
colorbitboxlightred10 &
colorbitboxlightred10 &
colorbitboxlightred10 &
colorbitboxlightred10 &
colorbitboxlightred10 &
colorbitboxlightred10 &
colorbitboxlightred10 &
colorbitboxlightred10 &
colorbitboxlightred10 &
colorbitboxlightred10 &
endbytefield
endcenter

or use an hexadecimal format to simplify typping

begincenter
beginbytefield[bitheight=widthof~Sign~,
boxformatting=centeringsmall]32
bitheader[endianness=big]31,30,23,22,0 \
colorbitboxlightcyan10 &
colorbitboxlightgreen80x80 &
colorbitboxlightred230x7A0800\
bitbox[]1rotatebox90Sign & bitbox[]8Exponent & bitbox[]23Mantissa\
endbytefield
endcenter
enddocument

ingrese la descripción de la imagen aquí

Si haces scroll puedes encontrar los informes de otros sys admins, tú igualmente eres capaz insertar el tuyo si lo deseas.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *