eu preciso de ajuda
Debezium ( https://debezium.io/ ) dígitos convertido decimais como um número inteiro string de base64 com precisão como parâmetro no JSON em java que decodificados como neste exemplo
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Base64;
public class HelloWorld{
public static void main(String []args){
String encoded = "lTBA";
int scale = 4;
final BigDecimal decoded = new BigDecimal(new BigInteger(Base64.getDecoder().decode(encoded)), scale);
System.out.println(decoded);
}
}
"lTBA" = -700
mas em golang Eu tenho alguns problemas no exemplo semelhante
pacote principal
import (
"encoding/base64"
"fmt"
"math/big"
)
func main() {
data, _ := base64.StdEncoding.DecodeString("lTBA")
bigInt := new(big.Int).SetBytes(data).String()
fmt.Println(bigInt)
}
https://play.golang.org/p/3Xdq9x6B9V- Ele retorna9777216
Porque quando eu uso setBytes em "math / grande / Int"-lo conjunto de dígitos como positivo sempre
// SetBytes interprets buf as the bytes of a big-endian unsigned
// integer, sets z to that value, and returns z.
func (z *Int) SetBytes(buf []byte) *Int {
z.abs = z.abs.setBytes(buf)
z.neg = false
return z
}
Construtor de do Java BigInteger
espera que o número em complemento de 2 representação binária, enquanto o Go big.Int.SetBytes()
espera um valor inteiro sem sinal (em ordem de bytes big-endian):
SetBytes interpreta buf como os bytes de um grande endian inteiro sem sinal , conjuntos de z para que o valor, e retorna z.
O que podemos fazer é continuar usando Int.SetBytes()
, mas se o número for negativo, temos que transformá-lo para o número dos dados binários representados em complemento de 2. Nós podemos dizer se é negativo se seu primeiro bit é 1 (que é o mais alto bit do primeiro byte).
Esta transformação é simples: se a entrada é representado usando n
bytes, construir um número utilizando n+1
bytes, onde o primeiro é 1
, o resto é 0
(o número máximo representável utilizando n
bytes mais 1). Subtraindo ( Int.Sub()
) a entrada deste número vai dar-lhe o valor absoluto do número em complemento de 2, por isso só temos de aplicar um sinal negativo sobre este número: Int.Neg()
.
A escala pode ser aplicada através da divisão ( Int.Div()
) o resultado por ser um número 10
scale
. Podemos construir tais número um anexando scale
zeros para um 1
.
Aqui está uma decode()
função que faz tudo isso. Não é otimizado para desempenho, mas ele faz o trabalho:
func decode(in string, scale int) (out *big.Int, err error) {
data, err := base64.StdEncoding.DecodeString(in)
if err != nil {
return
}
out = new(big.Int).SetBytes(data)
// Check if negative:
if len(data) > 0 && data[0]&0x80 != 0 {
// It's negative.
// Convert 2's complement negative to abs big-endian:
data2 := make([]byte, len(data)+1)
data2[0] = 1
temp := new(big.Int).SetBytes(data2)
out.Sub(temp, out)
// Apply negative sign:
out.Neg(out)
}
// Apply scale:
if scale > 0 {
temp, _ := new(big.Int).SetString("1"+strings.Repeat("0", scale), 10)
out.Div(out, temp)
}
return
}
Exemplo testando-a:
n, err := decode("lTBA", 4)
fmt.Println(n, err)
Saída (experimentá-lo na Go Playground ):
-700 <nil>