Lição: 014: Números de Ponto Fixo e Números Racionais em Solidity
Nesta aula, vamos explorar os conceitos de números de ponto fixo e números racionais em Solidity. Solidity, a linguagem de programação para contratos inteligentes do Ethereum, não suporta diretamente a aritmética de ponto flutuante. Em vez disso, os desenvolvedores podem usar representações de ponto fixo ou aproximações de números racionais para cálculos precisos. Vamos implementar esses conceitos por meio de exemplos.
Números de Ponto Fixo
Números de ponto fixo são uma forma de representar números não inteiros com um número fixo de casas decimais. Em Solidity, podemos implementar números de ponto fixo utilizando inteiros para representar o valor escalonado. Por exemplo, se quisermos representar o número 1,23 com duas casas decimais, podemos representá-lo como um inteiro 123.
Exemplo de Implementação de Ponto Fixo
Vamos implementar um contrato simples que usa representações de ponto fixo para cálculos.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract PontoFixo {
// Fator de escala para representar números de ponto fixo (2 casas decimais)
uint256 constant ESCALA = 100;
// Armazenar números de ponto fixo
struct NumeroPontoFixo {
uint256 valor; // A representação inteira escalonada pela ESCALA
}
// Função para criar um número de ponto fixo a partir de um decimal
function paraPontoFixo(uint256 valorDecimal) public pure returns (NumeroPontoFixo memory) {
return NumeroPontoFixo(valorDecimal * ESCALA);
}
// Função para converter de ponto fixo de volta para decimal
function paraDecimal(NumeroPontoFixo memory numPF) public pure returns (uint256) {
return numPF.valor / ESCALA;
}
// Função para adicionar dois números de ponto fixo
function somar(NumeroPontoFixo memory a, NumeroPontoFixo memory b) public pure returns (NumeroPontoFixo memory) {
return NumeroPontoFixo(a.valor + b.valor);
}
// Função para multiplicar dois números de ponto fixo
function multiplicar(NumeroPontoFixo memory a, NumeroPontoFixo memory b) public pure returns (NumeroPontoFixo memory) {
return NumeroPontoFixo((a.valor * b.valor) / ESCALA);
}
}
Explicação
-
Fator de Escala: A constante
ESCALA
é definida como 100, permitindo-nos representar números de ponto fixo com duas casas decimais. -
Estrutura: A estrutura
NumeroPontoFixo
armazena o valor inteiro escalonado. -
Funções de Conversão:
paraPontoFixo
converte um número decimal em um número de ponto fixo.paraDecimal
converte um número de ponto fixo de volta para um decimal.
-
Funções Aritméticas:
- A função
somar
adiciona dois números de ponto fixo. - A função
multiplicar
multiplica dois números de ponto fixo, ajustando para a escala.
- A função
Números Racionais
Números racionais são aqueles que podem ser expressos como o quociente de dois inteiros. Como Solidity não suporta diretamente tipos de números racionais, podemos representá-los usando um numerador e um denominador.
Exemplo de Implementação de Números Racionais
Vamos implementar um contrato simples para números racionais.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract NumeroRacional {
// Armazenar números racionais como numerador e denominador
struct Racional {
int256 numerador;
int256 denominador;
}
// Função para criar um número racional
function criarRacional(int256 numerador, int256 denominador) public pure returns (Racional memory) {
require(denominador != 0, "O denominador não pode ser zero");
return Racional(numerador, denominador);
}
// Função para adicionar dois números racionais
function somar(Racional memory a, Racional memory b) public pure returns (Racional memory) {
int256 novoNumerador = (a.numerador * b.denominador) + (b.numerador * a.denominador);
int256 novoDenominador = a.denominador * b.denominador;
return Racional(novoNumerador, novoDenominador);
}
// Função para multiplicar dois números racionais
function multiplicar(Racional memory a, Racional memory b) public pure returns (Racional memory) {
return Racional(a.numerador * b.numerador, a.denominador * b.denominador);
}
// Função para converter número racional em decimal
function paraDecimal(Racional memory r) public pure returns (int256) {
require(r.denominador != 0, "O denominador não pode ser zero");
return r.numerador / r.denominador;
}
}
Explicação
-
Estrutura: A estrutura
Racional
mantém um numerador e um denominador. -
Função de Criação: A função
criarRacional
inicializa um número racional e garante que o denominador não seja zero. -
Funções Aritméticas:
- A função
somar
calcula a soma de dois números racionais encontrando um denominador comum. - A função
multiplicar
simplesmente multiplica os numeradores e denominadores.
- A função
-
Função de Conversão: A função
paraDecimal
converte um número racional em sua forma decimal.
Conclusão
Nesta aula, aprendemos a implementar números de ponto fixo e números racionais em Solidity. Ambas as representações são essenciais para alcançar cálculos precisos, especialmente ao lidar com aplicações financeiras ou dados que exigem alta fidelidade. Ao utilizar aritmética inteira e tipos de dados estruturados, podemos gerenciar efetivamente valores não inteiros dentro de nossos contratos inteligentes.