github.com/Tri-stone/burrow@v0.25.0/binary/integer_test.go (about)

     1  package binary
     2  
     3  import (
     4  	"math"
     5  	"math/big"
     6  	"testing"
     7  
     8  	"strconv"
     9  	"strings"
    10  
    11  	"fmt"
    12  
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  func TestIsUint64SumOverflow(t *testing.T) {
    18  	var b uint64 = 0xdeadbeef
    19  	var a uint64 = math.MaxUint64 - b
    20  	assert.False(t, IsUint64SumOverflow(a-b, b))
    21  	assert.False(t, IsUint64SumOverflow(a, b))
    22  	assert.False(t, IsUint64SumOverflow(a+b, 0))
    23  	assert.True(t, IsUint64SumOverflow(a, b+1))
    24  	assert.True(t, IsUint64SumOverflow(a+b, 1))
    25  	assert.True(t, IsUint64SumOverflow(a+1, b+1))
    26  }
    27  
    28  func zero() *big.Int {
    29  	return new(big.Int)
    30  }
    31  
    32  var big2E255 = zero().Lsh(big1, 255)
    33  var big2E256 = zero().Lsh(big1, 256)
    34  var big2E257 = zero().Lsh(big1, 257)
    35  
    36  func TestU256(t *testing.T) {
    37  	expected := big2E255
    38  	encoded := U256(expected)
    39  	assertBigIntEqual(t, expected, encoded, "Top bit set big int is fixed point")
    40  
    41  	expected = zero()
    42  	encoded = U256(big2E256)
    43  	assertBigIntEqual(t, expected, encoded, "Ceiling bit is exact overflow")
    44  
    45  	expected = zero().Sub(big2E256, big1)
    46  	encoded = U256(expected)
    47  	assertBigIntEqual(t, expected, encoded, "Max unsigned big int is fixed point")
    48  
    49  	expected = big1
    50  	encoded = U256(zero().Add(big2E256, big1))
    51  	assertBigIntEqual(t, expected, encoded, "Overflow by one")
    52  
    53  	expected = big2E255
    54  	encoded = U256(zero().Add(big2E256, big2E255))
    55  	assertBigIntEqual(t, expected, encoded, "Overflow by doubling")
    56  
    57  	negative := big.NewInt(-234)
    58  	assert.Equal(t, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16",
    59  		fmt.Sprintf("%X", U256(negative).Bytes()), "byte representation is twos complement")
    60  
    61  	expected, ok := zero().SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF16", 16)
    62  	require.True(t, ok)
    63  	assertBigIntEqual(t, expected, U256(negative), "Bytes representation should be twos complement")
    64  
    65  	expected = zero()
    66  	encoded = U256(zero().Neg(big2E256))
    67  	assertBigIntEqual(t, expected, encoded, "Floor bit is overflow")
    68  
    69  	expected = big2E255
    70  	encoded = zero().Neg(big2E255)
    71  	encoded = U256(encoded)
    72  	assertBigIntEqual(t, expected, encoded, "2**255 is Self complement")
    73  
    74  	expected = zero().Add(big2E255, big1)
    75  	encoded = zero().Neg(big2E255)
    76  	encoded = encoded.Add(encoded, big1)
    77  	encoded = U256(encoded)
    78  	assertBigIntEqual(t, expected, encoded, "")
    79  }
    80  
    81  func TestS256(t *testing.T) {
    82  	expected := zero().Neg(big2E255)
    83  	signed := S256(big2E255)
    84  	assertBigIntEqual(t, expected, signed, "Should be negative")
    85  
    86  	expected = zero().Sub(big2E255, big1)
    87  	signed = S256(expected)
    88  	assertBigIntEqual(t, expected, signed, "Maximum twos complement positive is fixed point")
    89  
    90  	expected = zero()
    91  	signed = S256(expected)
    92  	assertBigIntEqual(t, expected, signed, "Twos complement of zero is fixed poount")
    93  
    94  	// Technically undefined but let's not let that stop us
    95  	expected = zero().Sub(big2E257, big2E256)
    96  	signed = S256(big2E257)
    97  	assertBigIntEqual(t, expected, signed, "Out of twos complement bounds")
    98  }
    99  
   100  func TestPutUint64BE(t *testing.T) {
   101  	bs := make([]byte, 8)
   102  	PutUint64BE(bs, 245343)
   103  	assert.Equal(t, "000000000003BE5F", fmt.Sprintf("%X", bs))
   104  }
   105  
   106  func TestSignExtend(t *testing.T) {
   107  	assertSignExtend(t, 16, 0,
   108  		"0000 0000 1001 0000",
   109  		"1111 1111 1001 0000")
   110  
   111  	assertSignExtend(t, 16, 1,
   112  		"1001 0000",
   113  		"1001 0000")
   114  
   115  	assertSignExtend(t, 32, 2,
   116  		"0000 0000 1000 0000 1101 0011 1001 0000",
   117  		"1111 1111 1000 0000 1101 0011 1001 0000")
   118  
   119  	assertSignExtend(t, 32, 2,
   120  		"0000 0000 0000 0000 1101 0011 1001 0000",
   121  		"0000 0000 0000 0000 1101 0011 1001 0000")
   122  
   123  	// Here we have a stray bit set in the 4th most significant byte that gets wiped out
   124  	assertSignExtend(t, 32, 2,
   125  		"0001 0000 0000 0000 1101 0011 1001 0000",
   126  		"0000 0000 0000 0000 1101 0011 1001 0000")
   127  	assertSignExtend(t, 32, 2,
   128  		"0001 0000 1000 0000 1101 0011 1001 0000",
   129  		"1111 1111 1000 0000 1101 0011 1001 0000")
   130  
   131  	assertSignExtend(t, 32, 3,
   132  		"0001 0000 1000 0000 1101 0011 1001 0000",
   133  		"0001 0000 1000 0000 1101 0011 1001 0000")
   134  
   135  	assertSignExtend(t, 32, 3,
   136  		"1001 0000 1000 0000 1101 0011 1001 0000",
   137  		"1001 0000 1000 0000 1101 0011 1001 0000")
   138  
   139  	assertSignExtend(t, 64, 3,
   140  		"0000 0000 0000 0000 0000 0000 0000 0000 1001 0000 1000 0000 1101 0011 1001 0000",
   141  		"1111 1111 1111 1111 1111 1111 1111 1111 1001 0000 1000 0000 1101 0011 1001 0000")
   142  
   143  	assertSignExtend(t, 64, 3,
   144  		"0000 0000 0000 0000 0000 0000 0000 0000 0001 0000 1000 0000 1101 0011 1001 0000",
   145  		"0000 0000 0000 0000 0000 0000 0000 0000 0001 0000 1000 0000 1101 0011 1001 0000")
   146  }
   147  
   148  func assertSignExtend(t *testing.T, bitSize int, bytesBack uint64, inputString, expectedString string) bool {
   149  	input := intFromString(t, bitSize, inputString)
   150  	expected := intFromString(t, bitSize, expectedString)
   151  	//actual := SignExtend(big.NewInt(bytesBack), big.NewInt(int64(input)))
   152  	actual := SignExtend(bytesBack, big.NewInt(int64(input)))
   153  	var ret bool
   154  	switch bitSize {
   155  	case 8:
   156  		ret = assert.Equal(t, uint8(expected), uint8(actual.Int64()))
   157  	case 16:
   158  		ret = assert.Equal(t, uint16(expected), uint16(actual.Int64()))
   159  	case 32:
   160  		ret = assert.Equal(t, uint32(expected), uint32(actual.Int64()))
   161  	case 64:
   162  		ret = assert.Equal(t, uint64(expected), uint64(actual.Int64()))
   163  	default:
   164  		t.Fatalf("Cannot test SignExtend for non-Go-native bit size %v", bitSize)
   165  		return false
   166  	}
   167  	if !ret {
   168  
   169  	}
   170  	return ret
   171  }
   172  
   173  func assertBigIntEqual(t *testing.T, expected, actual *big.Int, messages ...string) bool {
   174  	return assert.True(t, expected.Cmp(actual) == 0, fmt.Sprintf("%s - not equal:\n%v (expected)\n%v (actual)",
   175  		strings.Join(messages, " "), expected, actual))
   176  }
   177  
   178  func intFromString(t *testing.T, bitSize int, binStrings ...string) uint64 {
   179  	binaryString := strings.Replace(strings.Join(binStrings, ""), " ", "", -1)
   180  	i, err := strconv.ParseUint(binaryString, 2, bitSize)
   181  	require.NoError(t, err)
   182  	return i
   183  }