Commit b75faeb2 authored by zhanghuiren's avatar zhanghuiren

support java data structrue

parent 660039bc
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
package gxbig package gxbig
import ( import (
"encoding/binary"
"fmt" "fmt"
"math/big" "math/big"
) )
...@@ -27,7 +28,13 @@ type Integer struct { ...@@ -27,7 +28,13 @@ type Integer struct {
bigInt big.Int bigInt big.Int
// for hessian // for hessian
Value string Signum int32
Mag []int
FirstNonzeroIntNum int
LowestSetBit int
BitLength int
BitCount int
} }
func (Integer) JavaClassName() string { func (Integer) JavaClassName() string {
...@@ -45,10 +52,45 @@ func (i *Integer) FromString(s string) error { ...@@ -45,10 +52,45 @@ func (i *Integer) FromString(s string) error {
return nil return nil
} }
// FromBytes set data from a 10-bases number bytes // FromMag set data from a array of big-endian unsigned uint32
func (i *Integer) FromBytes(bytes []byte) error { // @see https://docs.oracle.com/javase/8/docs/api/java/math/BigInteger.html#BigInteger-int-byte:A-
func (i *Integer) FromSignAndMag(signum int32, mag []int) {
if signum == 0 && len(mag) == 0 {
return
}
i.Signum = signum
i.Mag = mag
bytes := make([]byte, 4*len(i.Mag))
for j := 0; j < len(i.Mag); j++ {
binary.BigEndian.PutUint32(bytes[j*4:(j+1)*4], uint32(i.Mag[j]))
}
i.bigInt = *i.bigInt.SetBytes(bytes) i.bigInt = *i.bigInt.SetBytes(bytes)
return nil
if i.Signum == -1 {
i.bigInt.Neg(&i.bigInt)
}
}
func (i *Integer) GetSignAndMag() (signum int32, mag []int) {
signum = int32(i.bigInt.Sign())
bytes := i.bigInt.Bytes()
outOf4 := len(bytes) % 4
if outOf4 > 0 {
bytes = append(make([]byte, 4-outOf4), bytes...)
}
size := len(bytes) / 4
mag = make([]int, size)
for i := 0; i < size; i++ {
mag[i] = int(binary.BigEndian.Uint32(bytes[i*4 : (i+1)*4]))
}
return
} }
// GetBigInt getter // GetBigInt getter
...@@ -64,3 +106,7 @@ func (i *Integer) SetBigInt(bigInt big.Int) { ...@@ -64,3 +106,7 @@ func (i *Integer) SetBigInt(bigInt big.Int) {
func (i *Integer) String() string { func (i *Integer) String() string {
return i.bigInt.String() return i.bigInt.String()
} }
func (i *Integer) Bytes() []byte {
return i.bigInt.Bytes()
}
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
package gxbig package gxbig
import ( import (
"reflect"
"testing" "testing"
) )
...@@ -52,3 +53,48 @@ func TestInteger(t *testing.T) { ...@@ -52,3 +53,48 @@ func TestInteger(t *testing.T) {
}) })
} }
} }
func TestInteger_FromSignAndMag(t *testing.T) {
type args struct {
signum int32
mag []int
}
tests := []struct {
name string
digit string
args args
}{
{`0`, `0`, args{0, []int{}}},
{`1`, `1`, args{1, []int{1}}},
{`2147483647`, `2147483647`, args{1, []int{2147483647}}},
{`4294967295`, `4294967295`, args{1, []int{4294967295}}},
{`4294967296`, `4294967296`, args{1, []int{1, 0}}},
{`4294967298`, `4294967298`, args{1, []int{1, 2}}},
{`1x2x3`, `18446744082299486211`, args{1, []int{1, 2, 3}}},
{`-1`, `-1`, args{-1, []int{1}}},
{`-4294967296`, `-4294967296`, args{-1, []int{1, 0}}},
{`-4294967298`, `-4294967298`, args{-1, []int{1, 2}}},
{`-1x2x3`, `-18446744082299486211`, args{-1, []int{1, 2, 3}}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
i := &Integer{}
i.FromSignAndMag(tt.args.signum, tt.args.mag)
if i.String() != tt.digit {
t.Errorf("digit %s got = %s", tt.digit, i.String())
}
s := &Integer{}
err := s.FromString(tt.digit)
if err != nil {
t.Error("FromString error = ", err)
}
sign, mag := s.GetSignAndMag()
if !(sign == tt.args.signum && reflect.DeepEqual(mag, tt.args.mag)) {
t.Error("want ", tt.args.signum, tt.args.mag,
"got", sign, mag)
}
})
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment