WEB3DEV

Cover image for Um decimal e um binário entram em uma biblioteca: Duas opções para matemática em Solidity 🔢
Adriano P. Araujo
Adriano P. Araujo

Posted on

Um decimal e um binário entram em uma biblioteca: Duas opções para matemática em Solidity 🔢

Este artigo é uma tentativa de entender e explicar as diferenças entre a biblioteca FixedPointMathLib da Solady e a biblioteca ABDKMath64x64 da ABDK Consulting para Solidity, bem como seus casos de uso. Acompanhe-me nesta exploração e aprimore seu desenvolvimento em Solidity com insights para escolher a biblioteca certa para seus projetos blockchain.


Com um entendimento razoável de como a biblioteca matemática FixedPointMathLib funciona, é hora de explorar a ABDKMath64x64, outra biblioteca poderosa para trabalhar com números de ponto fixo em Solidity. Você pode encontrar o código da biblioteca aqui no GitHub).

Essa biblioteca capacita desenvolvedores a realizar operações aritméticas básicas, bem como funções matemáticas mais avançadas, como logaritmos, médias, raízes quadradas, exponenciação e muito mais. Ela opera com dois números int128 de ponto fixo e retorna o resultado como um int256, eliminando o risco de estouro. No entanto, se o resultado ultrapassar a faixa de ±2¹²⁸, ele não poderá ser acomodado na representação 64.64-bit e a operação falhará.

Nesse contexto, um número de ponto fixo assinado de 64.64-bit é essencialmente uma fração com um inteiro de 128-bit assinado como numerador e um denominador fixo de 2⁶⁴. Como o denominador permanece constante, não há necessidade de armazená-lo. Consequentemente, os números de ponto fixo assinados de 64.64-bit são representados como int128, contendo apenas o numerador. É assim que um número de 64.64-bit é conceitualmente estruturado:

  • Os 64 bits antes do ponto representam o numerador.

  • Os 64 bits após o ponto representam o denominador.

Esses números oferecem uma ampla faixa com uma precisão respeitável, tornando-os adequados para aplicativos que exigem cálculos precisos de números reais. O uso da representação binária também permite operações de deslocamento de bits, possibilitando uma ampla manipulação de dados com o custo de uma maior complexidade.

O int128 inteiro é usado para representar o número, e o ponto separador é conceitual. O valor é deslocado para a esquerda por 2⁶⁴ no código para cálculos reais.

Por exemplo, o valor 5 não é representado como o familiar 5 decimal. Em vez disso, ele aparece como 0x00000000000000050000000000000000, o que é equivalente a 92233720368547758080 (5 * 2⁶⁴) no formato decimal. Os primeiros 16 bytes (64 bits) compreendem o numerador, enquanto os 16 bytes restantes (64 bits) representam o denominador.

Se quisermos ter certeza de obter o valor decimal, podemos usar a função toUint() da mesma biblioteca para convertê-lo de volta.

  • **Números que excedem 2⁶⁴ não podem ser diretamente representados como ponto fixo 64.64-bit. 

  • Quantidades de tokens devem ser representadas como uint256, não no formato de ponto fixo 64.64-bit.**

Casos de Uso

Existem cenários em que a matemática fracionária é crucial ao lidar com valores monetários ou de ativos. Alguns casos de uso podem incluir:

  • Cálculos de taxas de juros: quando você trabalha com taxas de juros, muitas vezes precisa usar números fracionários. Por exemplo, ao calcular juros compostos, pode ser necessário multiplicar o valor principal por uma taxa de juros fracionária várias vezes.

  • Economia de tokens: qm tokenomics gerais, muitas vezes é necessário dividir um valor monetário por outro para calcular proporções ou porcentagens. Por exemplo, você pode precisar calcular a porcentagem de tokens totais que uma determinada conta possui, o que envolveria dividir o número de tokens que a conta possui pelo número total de tokens.

  • Jogos: qode haver jogos em que cálculos matemáticos precisos podem fazer a diferença entre um vencedor e um perdedor. Jogos com um conceito semelhante ao NFTA.pl podem encontrar a ABDKMath64x64 como uma biblioteca valiosa para incorporar, pois ajudaria a determinar o jogador que está mais próximo de um preço, seja acima ou abaixo do preço.

A biblioteca ABDKMath64x64 oferece funções específicas para esses cenários, com funções como muli e mulu para multiplicação, e divi e divu para divisões (onde "u" denota uint e "i" denota int como entrada para a chamada da função).

Diferenças Chave

A principal distinção entre as bibliotecas ABDKMath64x64 e FixedPointMathLib reside na representação dos números. A primeira usa números binários com precisão de 2⁶⁴, enquanto a última usa números decimais.

Além disso, a ABDKMath64x64 não possui funções que arredondam para cima, mas oferece arredondamento em direção a zero além do arredondamento para baixo. Arredondar em direção a zero é um método de arredondamento de números em que a parte fracionária do número é removida, arredondando efetivamente o número em direção a zero. Por exemplo, se você arredondar 2.7 em direção a zero, obtém 2, e se você arredondar -2.7 em direção a zero, obtém -2. Por outro lado, se você arredondar 2.7 para cima, obtém 3, e se você arredondar -2.7 para cima, obtém -3.

Isso pode ser benéfico em situações em que você deseja evitar erros de arredondamento que podem resultar em um número arredondado para cima quando deveria ser arredondado para baixo, ou vice-versa.

Algumas outras distinções notáveis entre as bibliotecas podem incluir:

  • Versatilidade das funções: ABDKMath64x64 oferece uma ampla variedade de funções matemáticas, incluindo adição, subtração, multiplicação, divisão, valor absoluto, potência, raiz quadrada e muito mais. Essa versatilidade

 atende a várias operações matemáticas para aplicativos descentralizados. No entanto, a FixedPointMathLib oferece cerca do dobro de funções executáveis, ampliando assim sua gama de casos de uso.

  • Suporte para ponto fixo 64.64-bit: ABDKMath64x64 oferece suporte para operações com números de ponto fixo de 64.64-bit assinados, combinando uma ampla faixa com boa precisão e desempenho, tornando-o ideal para aplicativos que lidam com números reais. Em contraste, o FixedPointMathLib foi projetado para trabalhar com números decimais.

  • Eficiência de gás: devido à manipulação de dados em baixo nível e às conversões frequentes dentro da biblioteca, a biblioteca ABDKMath64x64 é um pouco menos eficiente em termos de gás do que a FixedPointMathLib. Aqui estão os custos de gás para a mesma multiplicação básica feita com cada biblioteca:

Como observado, o custo da multiplicação com ABDKMath64x64 é 78 unidades de gás mais caro do que com FixedPointMathLib.

Conclusão

A escolha entre essas bibliotecas dependerá das necessidades específicas do seu caso de uso. ABDKMath64x64 pode ser mais eficiente em termos de gás do que muitas outras bibliotecas, mas não é uma escolha melhor quando comparada à  _FixedPointMathLib _. Isso pode ser uma vantagem significativa em situações em que a eficiência de gás é um fator crítico.

No entanto, você também precisa considerar o tipo de números com os quais está trabalhando e as operações que precisa realizar.  ABDKMath64x64 usa números binários, o que pode adicionar complexidade desnecessária a alguns projetos. Se seu trabalho envolve principalmente números decimais, a  FixedPointMathLib pode ser mais adequada.

FixedPointMathLib, com seu amplo conjunto de funções e foco em números decimais, se adapta a uma ampla gama de aplicativos. A  ABDKMath64x64, com seu manuseio de números binários e precisão, é projetada para projetos em que a precisão é primordial. A escolha entre essas bibliotecas, em última análise, depende dos requisitos específicos do seu projeto, destacando a necessidade de um entendimento profundo de ambas.

Agora, se eu tivesse que escolher entre ambas, devido à sua ampla gama de casos de uso, notação decimal amigável ao usuário e custo-efetividade, eu optaria pela FixedPointMathLib da Solady.


Se você achou este artigo útil, sinta-se à vontade para mostrar seu apoio através de uma doação para o meu endereço ou via Kofi:

Sua contribuição será muito apreciada!


Este artigo foi escrito por Juan Xavier Valverde e traduzido por Adriano P. de Araujo. O original em inglês pode ser encontrado aqui.

Latest comments (0)