Código Natural/Notação posicional: mudanças entre as edições

m
 
(11 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 9: Linha 9:
|'''Código'''
|'''Código'''
|'''''Número'''''
|'''''Número'''''
|
|'''Código'''
|'''Código'''
|'''''Número'''''
|'''''Número'''''
|-
|-
|[[wikipedia:Binary number|Base 2. Binária]] / Ilegível ||<code>00010010</code>||''10010''  || <code>1111</code> || ''1111''
|[[wikipedia:Binary number|Base 2. Binária]] / Ilegível ||<code>000000010010</code>||''10010''  || ||<code>1111</code> || ''1111''
|-
|-
|[[wikipedia:Quaternary numeral system|Base 4. Quaternaria]] / Melhorou! ||<code>0102</code>||''102'' || <code>33</code> || ''33''
|[[wikipedia:Quaternary numeral system|Base 4. Quaternaria]] / Melhorou! ||<code>000102</code>||''102'' || ||<code>33</code> || ''33''
|-
|-
|[[wikipedia:Hexadecimal|Base 16. Hexadecimal]] / Mais compacta ||<code>12</code>||''12'' || <code>f</code> || ''f''
|[[wikipedia:Hexadecimal|Base 16. Hexadecimal]] / Compacta ||<code>012</code>||''12'' || ||<code>f</code> || ''f''
|}
|}


Alguns cuidados devem ser tomados, como o tratamento dos zeros a esquerda, importante diferenciador de códigos. Notar o exemplo {{baseNh|00010010|2}} que manteve seu zero a esquerda em {{baseNh|0102|4}}. E existem ainda códigos que não podem ser representados em certas bases. Por exemplo o código {{baseNh|010|2}} não pode ser representado na base 4. Se representar como {{baseNh|02|4}}  vai ser confundido com o binário {{baseNh|0010|2}}. Outros exemplos:
Notar o exemplo do código {{baseNh|000000010010|2}} que manteve seus zeros a esquerda na sua representação quaternária,  {{baseNh|000102|4}}. Os zeros a esquerda são importantes diferenciadores dos códigos, todavia existem restrições. Existem códigos binários que não podem ser representados nas bases numéricas usuais. Exemplos:


:{| class="wikitable"
:{| class="wikitable"
|'''Base2''' || <code>0</code> || <code>00</code> || <code>0000</code> || <code>010</code> || <code>1010</code> || <code>10100</code>
|'''Base2''' || '''<code>0</code>''' <br/><small>(1 dígito)</small>|| '''<code>00</code>''' <br/><small>(2 dígitos)</small> || '''<code>0000</code>'''  <br/><small>(4 dígitos)</small>|| '''<code>010</code>''' <br/><small>(3 dígitos)</small> || '''<code>1010</code>'''  <br/><small>(4 dígitos)</small> || '''<code>10100</code>''' <br/><small>(5 dígitos)</small> || '''<code>010100</code>''' <br/><small>(6 dígitos)</small> || '''<code>00010100</code>''' <br/><small>(8 dígitos)</small>
|-
|-
|'''Base4''' || ? || <code>0</code> || <code>00</code> || ? || <code>22</code> || ?
|'''Base4''' || <code style="color:red;font-size: x-large; font-weight:bold">?</code> || <code>0</code> || <code>00</code> || <code style="color:red;font-size: x-large; font-weight:bold">?</code> || <code>22</code> || <code style="color:red;font-size: x-large; font-weight:bold">?</code> || <code>110</code>|| <code>0110</code>
|-
|-
|'''Base16''' || ? || ? || <code>0</code> || ? || <code>a</code> || ?
|'''Base16''' || <code style="color:red;font-size: x-large; font-weight:bold">?</code> || <code style="color:red;font-size: x-large; font-weight:bold">?</code> || <code>0</code> || <code style="color:red;font-size: x-large; font-weight:bold">?</code> || <code>a</code> || <code style="color:red;font-size: x-large; font-weight:bold">?</code> || <code style="color:red;font-size: x-large; font-weight:bold">?</code> || <code>14</code>
|}
|}
O código {{baseNh|010|2}} não pode ser representado na base 4 pois se permitíssimos algo como "{{baseNh|02|4}}"  seria confundido com o binário {{baseNh|0010|2}}. Assim nas demais interrogações da ''base 4'', apenas os binários com uma quantidade par de dígitos (2, 4 e 6) podem ser representados. As interrogações da ''base 16'' surgem quando a quantidade de dígitos binários não é divisível por quatro &mdash; temos interrogações em 1, 2,  3, 5 ou  6 dígitos binários. 


== Definição ==
== Definição ==
Linha 163: Linha 166:


==== Base 32 ====
==== Base 32 ====
Ver [[wikipedia:Base 32]]. Para aplicações que requerem maior grau de compactação, a base 32 é a potência de 2 que se encontra entre os dois limites:
Ver [[wikipedia:Base 32]] e [[#Base_N|acima em Base N]] as variantes (''base32hex'', ''base32ghs'', etc.). Para aplicações que requerem maior grau de compactação, a ''base 32'' é a potência de 2 que se encontra ainda abaixo do limite  superior. São dois limites, conforme o tipo de aplicação:
* base36 é o limite alfanumérico resiliente, onde não há confusão entre maiúsculas e minúsculas.
 
* base 64 é o limite alfanumérico (10 + 26*2 + 2 caracteres ASCII usuais).
* ''base 36'' é o limite alfanumérico resiliente, onde não há confusão entre maiúsculas e minúsculas.<br/>É o limite adotado em aplicações que envolvem interpretação ou comunicação humanas, tais como voz, chat, URLs curtas, aplicações cartoriais, placas, etc. Algumas tecnologias, como QR-Codes também se beneficiam do case-insensitive.  Como 36 não é potência de 2 (portanto não é interoperável), o 32 é preferido como máximo.
 
* ''base 64'' é o limite alfanumérico (10 + 26*2 + 2 caracteres ASCII usuais).<br/>É o limite para aplicações onde é permitida a diferenciação maiúsculas/minúsculas. A bsase32 seria preferível à base64 em códigos de poucos bits, onde o ganho de compactação seja notado, e a oferta de hierarquia tenha um papel importante.
 
Até o momento foram aceitas apenas 4 "variantes padronizadas", conforme [[#Base N|tabela acima]]: ''base32hex'', ''base32ghs'', ''base32nvu'' e ''base32rfc''.


=== Base Nh ===
=== Base Nh ===
Linha 363: Linha 370:


=== Encode e decode Nh ===
=== Encode e decode Nh ===
A seguir os algoritmos completos, expresso através de [[wikipedia:PL/pgSQL|linguagem PLpgSQL]]. Do inglês "''encode''" codifica em base Nh, e "''decode''" decodifica a base Nh. Na linguagem SQL a representação interna em [[cadeia de bits]] é denominada ''varbit'' (ou [https://www.postgresql.org/docs/current/datatype-bit.html ''bit varying'']), abreviada como ''vbit''.  
A seguir os algoritmos completos, expressos como funções [[wikipedia:PL/pgSQL|linguagem PLpgSQL]]"''encode''" codifica em base Nh, e "''decode''" decodifica a base Nh.  
O "encode" é a conversão "vbit to base-h", o "decode" é a conversão "base-h to vbit", daí os nomes de função <code>vbit_to_baseh()</code> e  <code>baseh_to_vbit()</code>, no contexto do [https://git.osm.codes/NaturalCodes/tree/main/src-sql SQL-schema NatCode].
 
No [[wikipedia:SQL:1992|padrão SQL:1992]] a representação interna em [[cadeia de bits]] foi denominada ''BIT VARYING'', sendo [[wikipedia:SQL:2003|descontinuada em 2003]]. No PostgreSQL, todavia, [https://www.postgresql.org/docs/current/datatype-bit.html o tipo de dado] e seus [https://www.postgresql.org/docs/current/functions-bitstring.html operadores e funções] foram mantidos, sendo abreviado como ''varbit'' &mdash; e nos nomes de função da biblioteca NatCod abreviada como ''vbit''.
 
O "encode" é a conversão "vbit to base-h", o "decode" é a conversão "base-h to vbit". Daí os nomes de função <code>vbit_to_baseh()</code> e  <code>baseh_to_vbit()</code>, com implementação completa no [https://git.osm.codes/NaturalCodes/tree/main/src-sql SQL-schema NatCode]. A seguir os algoritmos simplificados.  


A seguir algoritmos simplificados. A função de "encode bitstring" converte uma cadeia de bits em texto base2h, base4h, base8h ou base16h.
Função simplificada de "encode bitstring", converte uma cadeia de bits em texto base-h.
<syntaxhighlight lang="sql">
<syntaxhighlight lang="sql">
CREATE FUNCTION natcod.vbit_to_baseh(
CREATE FUNCTION natcod.vbit_to_baseh(
Linha 378: Linha 387:
     ret text := '';
     ret text := '';
     blk varbit;
     blk varbit;
    blk_n int;
     bits_per_digit int;
     bits_per_digit int;
     tr int[] := '{ {1,2,0,0}, {1,3,4,0}, {1,3,5,6} }'::int[]; -- --4h(bits,pos), 8h(bits,pos)
     tr int[] := '{ {1,2,0,0}, {1,3,4,0}, {1,3,5,6} }'::int[]; -- --4h(bits,pos), 8h(bits,pos)
     tr_selected JSONb;
     tr_selected JSONb;
     trtypes JSONb := '{"2":[1,1], "4":[1,2], "8":[2,3], "16":[3,4]}'::JSONb; -- TrPos,bits. Can optimize? by sparse array.
     trtypes JSONb := '{"2":[1,1], "4":[1,2], "8":[2,3], "16":[3,4]}'::JSONb;
     trpos int;
     trpos int;
     baseh "char"[] := array[ -- the standards for Baseh:
     baseh "char"[] := array[ -- the standards for Baseh:
Linha 395: Linha 403:
BEGIN
BEGIN
   vlen := bit_length(p_val);
   vlen := bit_length(p_val);
   tr_selected := trtypes->(p_base::text);  -- can be array instead of JSON
   tr_selected := trtypes->(p_base::text);
  IF p_val IS NULL OR tr_selected IS NULL OR vlen=0 THEN
    RETURN NULL; -- or  p_retnull;
  END IF;
   IF p_base=2 THEN
   IF p_base=2 THEN
     RETURN $1::text; --- direct bit string as string
     RETURN $1::text; -- bit string as string
   END IF;
   END IF;
   bits_per_digit := (tr_selected->>1)::int;
   bits_per_digit := (tr_selected->>1)::int;
  blk_n := vlen/bits_per_digit;
   pos0  := (tr_selected->>0)::int;
   pos0  := (tr_selected->>0)::int;
   trpos := tr[pos0][bits_per_digit];
   trpos := tr[pos0][bits_per_digit];
   FOR counter IN 1..blk_n LOOP
   FOR counter IN 1..(vlen/bits_per_digit) LOOP
       blk := substring(p_val FROM 1 FOR bits_per_digit);
       blk := substring(p_val FROM 1 FOR bits_per_digit);
       ret := ret || baseh[trpos][ varbit_to_int(blk,bits_per_digit) ];
       ret := ret || baseh[trpos][ varbit_to_int(blk,bits_per_digit) ];
       p_val := substring(p_val FROM bits_per_digit+1); -- same as p_val<<(bits_per_digit*blk_n)
       p_val := substring(p_val FROM bits_per_digit+1);
   END LOOP;
   END LOOP;
   vlen := bit_length(p_val);
   vlen := bit_length(p_val);
   IF p_val!=b'' THEN -- vlen % bits_per_digit>0
   IF p_val!=b'' THEN
     trpos := tr[pos0][vlen];
     trpos := tr[pos0][vlen];
     ret := ret || baseh[trpos][ varbit_to_int(p_val,vlen) ];
     ret := ret || baseh[trpos][ varbit_to_int(p_val,vlen) ];
Linha 421: Linha 425:
</syntaxhighlight>
</syntaxhighlight>


Função geral de "decode base Nh". Converte o texto base Nh para sua representação interna ''bitstring''.
Função geral de "decode base Nh". Converte o texto base-h para sua representação interna ''bitstring''.


<syntaxhighlight lang="sql">
<syntaxhighlight lang="sql">
CREATE FUNCTION natcod.baseh_to_vbit(
CREATE FUNCTION natcod.baseh_to_vbit(
   p_val text,  -- input (enforced lower case)
   p_val text,  -- input (enforced lower case)
   p_base int DEFAULT 4 -- selecting base2h, base4h, base8h, or base16h.
   p_base int DEFAULT 16 -- selecting base2h, base4h, base8h, or base16h.
) RETURNS varbit AS $f$
) RETURNS varbit AS $f$
DECLARE
DECLARE
   tr_hdig jsonb := '{
   tr_hdig jsonb := '{
     "g":[1,0],"q":[1,1],
     "G":[1,0],"Q":[1,1],
     "h":[2,0],"m":[2,1],"r":[2,2],"v":[2,3],
     "H":[2,0],"M":[2,1],"R":[2,2],"V":[2,3],
     "j":[3,0],"k":[3,1],"n":[3,2],"p":[3,3],
     "J":[3,0],"K":[3,1],"N":[3,2],"P":[3,3],
     "s":[3,4],"t":[3,5],"z":[3,6],"y":[3,7]
     "S":[3,4],"T":[3,5],"Z":[3,6],"Y":[3,7]
   }'::jsonb;
   }'::jsonb;
   tr_full jsonb := '{
   tr_full jsonb := '{
Linha 446: Linha 450:
   BEGIN
   BEGIN
   ret = '';
   ret = '';
   blk := regexp_match(p_val,'^([0-9a-f]*)([ghjkmnp-tvzy])?$');
   blk := regexp_match(p_val,'^([0-9a-f]*)([GHJKMNP-TVZY])?$');
   IF blk[1] >'' THEN
   IF blk[1] >'' THEN
     FOREACH i IN ARRAY regexp_split_to_array(blk[1],'') LOOP
     FOREACH i IN ARRAY regexp_split_to_array(blk[1],'') LOOP
Linha 477: Linha 481:
Na ''Base 16h'' portanto apresenta rótulos para todos os níveis, do L0 ao L4 e seus intermediários: ''L0'',&nbsp;''L0.5'', ''L1'', ''L1.5'', ''L2'', ''L2.5'', ''L3, L3.5'',&nbsp;''L4.''  Resulta em um sistema com 5×2-1=9 grades hierárquicas, conforme a ilustração acima. Para qualquer que seja o nível máximo ''LM'' (no exemplo ''L4'' portanto ''M''=4), a Base&nbsp;16h resultará em um '''sistema completo de grades''', com ''(M+1)''×2-1 níveis.
Na ''Base 16h'' portanto apresenta rótulos para todos os níveis, do L0 ao L4 e seus intermediários: ''L0'',&nbsp;''L0.5'', ''L1'', ''L1.5'', ''L2'', ''L2.5'', ''L3, L3.5'',&nbsp;''L4.''  Resulta em um sistema com 5×2-1=9 grades hierárquicas, conforme a ilustração acima. Para qualquer que seja o nível máximo ''LM'' (no exemplo ''L4'' portanto ''M''=4), a Base&nbsp;16h resultará em um '''sistema completo de grades''', com ''(M+1)''×2-1 níveis.


Abaixo células ''L0'' de cobertura base16 do Brasil, ilustrando caso concreto de grades de diferentes níveis. Elas foram rotuladas pela Curva-Z espelhada verticalmente.
Abaixo células ''L0'' de cobertura base16 do Brasil, ilustrando caso concreto de grades de diferentes níveis. Elas foram rotuladas pela Curva-Z espelhada verticalmente &mdash; a orientação adotada nos eixos resulta em variantes da curva (N e И) e da sua ordenação.


[[Arquivo:XY-FlippedVertically.png|centro|semmoldura|420px]]
[[Arquivo:XY-FlippedVertically.png|centro|semmoldura|480px]]


[[Arquivo:BR-SciCode-Base16h.png|centro|720x720px]]
[[Arquivo:BR-SciCode-Base16h.png|centro|720x720px]]
2 391

edições