Documentation
¶
Overview ¶
Package math
该文件内定义了两个结构体:HexOrDecimal256和Decimal256,它们的底层实现都是big.Int,定义这两个结构体是为了实现对big.Int进行 marshal/unmarshal,它们俩都各自实现了MarshalText和UnmarshalText方法,HexOrDecimal256和Decimal256不同的地方在于:
- HexOrDecimal256 的MarshalText方法会将大整数编码成16进制数,并在前面加上"0x"前缀,而 Decimal256 只会在原10进制数 两边加上双引号得到字符串,然后再将字符串转换成字节切片,更本不会将原大整数转换成16进制,更不会在前面加上"0x"前缀。
- HexOrDecimal256 的UnmarshalText和 Decimal256 功能一样,都能将含有前缀的16进制或者不含前缀的10进制数据解析成大整数。
需要注意的地方是,无论 HexOrDecimal256 还是 Decimal256,它们所能支持的大整数必须在256比特以内。
随后,该文件还定义了以下方法:
func BigPow(a, b int64) *big.Int
func BigMax(x, y *big.Int) *big.Int
func BigMin(x, y *big.Int) *big.Int
func FirstBitSet(i *big.Int) int
func ReadBits(bigInt *big.Int, buf []byte)
func PaddedBigBytes(bigInt *big.Int, n int) []byte
func Byte(bigInt *big.Int, padLen, n int) byte
U256Bytes 方法将一个给定的大整数(比特位小于等于256)填充为一个含有32个字节的大整数,从而转换成乙太坊虚拟机里的支持的数字
func U256Bytes(n *big.Int) []byte
S256 方法接受一个大整数x作为入参,如果x小于2^255,则直接返回x,否则计算x-2^256,并返回计算结果
func S256(x *big.Int) *big.Int
Exp 方法接受两个大整数base和exponent作为入参,然后计算result=base^exponent,并将result返回
func Exp(base, exponent *big.Int) *big.Int
Package math ¶
该文件类定义了一个类型:HexOrDecimal64,该类型的地层实现是uint64,通过它实现了对uint64进行marshal/unmarshal,marshal会将 64位无符号整型编码成含有"0x"前缀的16进制数,unmarshal支持将含有"0x"或"0X"前缀的16进制数或者10进制数转换成64位无符号整型。
此外,该文件还定义了如下全局函数:
- func SafeSub(x, y uint64) (uint64, bool)
- func SafeAdd(x, y uint64) (uint64, bool)
- func SafeMul(x, y uint64) (uint64, bool)
以上三个全局函数的第二个返回值反映了对两个64位无符号整型进行加、减乘操作后是否会出现溢出。如果溢出,则第二个返回值为true。
Index ¶
- Constants
- Variables
- func BigMax(x, y *big.Int) *big.Int
- func BigMin(x, y *big.Int) *big.Int
- func BigPow(a, b int64) *big.Int
- func Byte(bigInt *big.Int, padLen, n int) byte
- func Exp(base, exponent *big.Int) *big.Int
- func FirstBitSet(i *big.Int) int
- func MustParseBig256(s string) *big.Int
- func MustParseUint64(s string) uint64
- func PaddedBigBytes(bigInt *big.Int, n int) []byte
- func ParseBig256(s string) (*big.Int, bool)
- func ParseUint64(s string) (uint64, bool)
- func ReadBits(bigInt *big.Int, buf []byte)
- func S256(x *big.Int) *big.Int
- func SafeAdd(x, y uint64) (uint64, bool)
- func SafeMul(x, y uint64) (uint64, bool)
- func SafeSub(x, y uint64) (uint64, bool)
- func U256(x *big.Int) *big.Int
- func U256Bytes(n *big.Int) []byte
- type Decimal256
- type HexOrDecimal256
- type HexOrDecimal64
Constants ¶
const ( // WordBits 用来表示一个 big.Word 可以存放多少个比特位,在64位的Ubuntu 20.04操作系统中,wordBits等于64。 WordBits = 32 << (uint64(^(big.Word(0))) >> 63) // WordBytes 用来表示一个 big.Word 最多可以存放多少个字节,在64位的Ubuntu 20.04操作系统中,wordBytes等于8。 WordBytes = WordBits / 8 )
const ( // MaxInt8 <=> 01111111 MaxInt8 = 1<<7 - 1 // MinInt8 <=> 10000000 MinInt8 = -1 << 7 // MaxInt16 <=> 01111111,11111111 MaxInt16 = 1<<15 - 1 // MinInt16 <=> 10000000,00000000 MinInt16 = -1 << 15 // MaxInt32 <=> 01111111,11111111,11111111,11111111 MaxInt32 = 1<<31 - 1 // MinInt32 <=> 10000000,00000000,00000000,00000000 MinInt32 = -1 << 31 // MaxInt64 <=> 01111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111 MaxInt64 = 1<<63 - 1 // MinInt64 <=> 10000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000 MinInt64 = -1 << 63 // MaxUint8 <=> 11111111 MaxUint8 = 1<<8 - 1 // MaxUint16 <=> 11111111,11111111 MaxUint16 = 1<<16 - 1 // MaxUint32 <=> 11111111,11111111,11111111,11111111 MaxUint32 = 1<<32 - 1 // MaxUint64 <=> 11111111,11111111,11111111,11111111,11111111,11111111,11111111,11111111 MaxUint64 = 1<<64 - 1 )
Variables ¶
Functions ¶
func Byte ¶
Byte ♏ |作者:吴翔宇| 🍁 |日期:2022/10/28|
Byte 方法接受三个入参,第一个入参是一个大整数bigInt,第二和第三两个入参分别是padLen和n,需要注意的是padLen这个参数, 它表示对原始大整数进行填充后大整数所含有的字节数,这里指的填充可以认为是调用 PaddedBigBytes 方法对大整数进行填充。该 方法的目的就是获取bigInt中从最高位字节开始第n个字节的值,与 bigEndianByteAt 这个方法的目的正好相反,实际上,Byte 方 法就是通过调用 bigEndianByteAt 方法实现的:return bigEndianByteAt(bigInt, padLen-1-n)
例如,先定义一个大整数bigInt=4328719365,它的字节切片表现形式是:[1 2 3 4 5],调用 PaddedBigBytes(bigInt, 17) 方法对其进行填充,从bigInt的最低地址位开始填充12个0:[0 0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5],然后给定padLen=17和 n=13,调用bigEndianByteAt(bigInt, 3),根据 bigEndianByteAt 的规则从最低有效字节处开始,返回第3个字节,即byte(2)。
func Exp ¶
Exp ♏ |作者:吴翔宇| 🍁 |日期:2022/10/28|
Exp 方法接受两个大整数base和exponent作为入参,然后计算result=base^exponent,并将result返回。 如果计算得到的result所表示的数需要超过256个比特位存储,那么仅保留低位的256个比特。
func FirstBitSet ¶
FirstBitSet ♏ |作者:吴翔宇| 🍁 |日期:2022/10/28|
该方法接受一个大整数作为入参,该方法从给定的大整数i的最低位开始遍历,直到遇到第一个比特位等于1的位置结束, 并返回该位置处的比特索引位置(最低有效位),如果找不到,则直接返回该大整数的比特长度。
例如:给定一个大整数:134348928,它的二进制表现形式是:0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 它的最低有效位则是7。
func MustParseBig256 ¶
MustParseBig256 ♏ |作者:吴翔宇| 🍁 |日期:2022/10/28|
该方法实际上就是调用 ParseBig256 方法,如果 ParseBig256 无法解析字符串得到大整数,则直接panic。
func MustParseUint64 ¶
MustParseUint64 ♏ |作者:吴翔宇| 🍁 |日期:2022/10/29|
MustParseUint64 方法接受一个字符串参数s,s应该是一个含有"0x"或"0X"前缀的16进制数,或者是一个10进制数, 然后 MustParseUint64 方法将s解析成一个uint64类型的10进制整数。该方法实际上是对 ParseUint64 方法的包 装,如果 ParseUint64 的第二个参数返回false,则 MustParseUint64 直接panic。
func PaddedBigBytes ¶
PaddedBigBytes ♏ |作者:吴翔宇| 🍁 |日期:2022/10/28|
PaddedBigBytes 该方法接受两个参数,第一个入参是一个大整数bigInt,第二个参数是一个整数n,该方法的目的 就是在不改变bigInt大小的情况下,给bigInt填充n-bigInt.BitLen()/8个空字节。
例如,给定的大整数bigInt=575648,它的字节切片表现形式是:[8 200 160]=[0001000 11001000 10100000]; 然后给定的n为5,那么经过填充后,得到的结果是:[0 0 8 200 160]。
func ParseBig256 ¶
ParseBig256 ♏ |作者:吴翔宇| 🍁 |日期:2022/10/28|
PareBig256 方法将给定的字符串解析成一个大整数,给定的字符串要么含有"0x"或"0X"前缀,要么不含有,这会决定不同的解析方式:
- 如果给定的字符串含有前缀,则给定的字符串必须满足以下两个条件才能解析成功: - 字符串里除了前缀外,其余字符的取值范围只能在{0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F}里 - 实际上,尽管给的字符串是16进制的,但是解析后得到大整数是10进制形式的,如果解析后的结果需要超过256位比特去存储,则该 方法认为解析失败,默认解析后所能获得的最大整数是: 115792089237316195423570985008687907853269984665640564039457584007913129639935
- 如果给定的字符串不含有前缀,则给定的字符串必须满足以下两个条件才能解析成功: - 字符串里每个字符的取值范围只能在{0 1 2 3 4 5 6 7 8 9}里 - 解析后得到的大整数必须小于115792089237316195423570985008687907853269984665640564039457584007913129639935 给出两个例子: - 输入"0x12a",得到:298 - 输入"123",得到:123
func ParseUint64 ¶
ParseUint64 ♏ |作者:吴翔宇| 🍁 |日期:2022/10/29|
ParseUint64 方法接受一个字符串参数s,s应该是一个含有"0x"或"0X"前缀的16进制数,或者是一个10进制数, 然后 ParseUint64 方法将s解析成一个uint64类型的10进制整数。如果s的格式存在错误,该方法返回的第二个 参数将会是false。
例如:给定的s="0x123",得到整数:291;如果给定的s="123",得到整数:123。
func ReadBits ¶
ReadBits ♏ |作者:吴翔宇| 🍁 |日期:2022/10/28|
ReadBits 接受两个入参,第一个入参是一个大整数bigInt,第二个入参是一个字节切片buf,该方的功能就是将给 定的大整数的所有比特位拷贝到给定的字节切片里(从buf的右边开始拷贝),如果给定的字节切片不够长,就拷贝 len(buf)*8个比特;如果太长,字节切片左边剩下的字节就置为0.
func S256 ¶
S256 ♏ |作者:吴翔宇| 🍁 |日期:2022/10/28|
S256 方法接受一个大整数x作为入参,如果x小于2^255,则直接返回x,否则计算x-2^256,并返回计算结果。
例如:给定的x=2^255+1,执行该方法后得到结果:-57896044618658097711785492504343953926634992332820282019728792003956564819967
func SafeAdd ¶
SafeAdd ♏ |作者:吴翔宇| 🍁 |日期:2022/10/29|
该方法接受两个64位无符号整数x和y,然后计算result=x+y,返回的result也是64位无符号整数,如果计算结果溢出, 则该方法返回的第二个参数等于true。
例如,给定x = MaxUint64 - 1,y = 2,得到输出是(1, true);再给定x = MaxUint64 - 1,y = 1,得到 结果是(18446744073709551615, false)。
func SafeMul ¶
SafeMul ♏ |作者:吴翔宇| 🍁 |日期:2022/10/29|
该方法接受两个64位无符号整数x和y,然后计算result=x*y,返回的result也是64位无符号整数,如果计算结果溢出, 则该方法返回的第二个参数等于true。
例如,给定x = MaxUint64 / 2,y = 3,得到输出是(9223372036854775805, true);再给定x = MaxUint64 / 2, y = 2,得到结果是(18446744073709551614, false)。
func SafeSub ¶
SafeSub ♏ |作者:吴翔宇| 🍁 |日期:2022/10/29|
该方法接受两个64位无符号整数x和y,然后计算result=x-y,返回的result也是64位无符号整数,如果计算结果溢出, 则该方法返回的第二个参数等于true。
例如,给定x=3,y=5,得到输出是(18446744073709551614, true);再给定x=3,y=2,得到输出是(1, false)。
Types ¶
type Decimal256 ¶
Decimal256 ♏ |作者:吴翔宇| 🍁 |日期:2022/10/28|
Decimal256 类型的底层实现是 big.Int,定义该类型是为了实现对大整数的marshal/unmarshal,Decimal256 实现了 MarshalText 和 UnmarshalText 两个方法,Decimal256 与 HexOrDecimal256 不同的地方在于,Decimal256 的 MarshalText 方法不会把数字编码成16进制形式,即不会含有"0x"或"0X"前缀;但是 Decimal256 支持对含有前缀的字节 切片进行解码,并且解码得到的是10进制的大整数。
func NewDecimal256 ¶
func NewDecimal256(x int64) *Decimal256
NewDecimal256 ♏ |作者:吴翔宇| 🍁 |日期:2022/10/28|
NewDecimal256 方法接受一个int64类型的数字作为入参,然后将其转换为 Decimal256 类型。
func (*Decimal256) MarshalText ¶
func (d *Decimal256) MarshalText() ([]byte, error)
MarshalText ♏ |作者:吴翔宇| 🍁 |日期:2022/10/28|
MarshalText 方法实现了 encoding.TextMarshaler 接口,直接给数字的两端加上双引号得到字符串, 然后将字符串转换为字节切片并返回。
func (*Decimal256) String ¶
func (d *Decimal256) String() string
String ♏ |作者:吴翔宇| 🍁 |日期:2022/10/28|
该方法返回 Decimal256 的字符串形式。
func (*Decimal256) UnmarshalText ¶
func (d *Decimal256) UnmarshalText(input []byte) error
UnmarshalText ♏ |作者:吴翔宇| 🍁 |日期:2022/10/28|
该方法实现了 encoding.TextUnmarshaler 接口,将给定的字节切片转换为十进制的大整数,给定的字节切片需要 满足以下两个条件:
- 字符串里每个字符的取值范围只能在{0 1 2 3 4 5 6 7 8 9}里
- 解码后得到的大整数必须小于115792089237316195423570985008687907853269984665640564039457584007913129639935
type HexOrDecimal256 ¶
HexOrDecimal256 ♏ |作者:吴翔宇| 🍁 |日期:2022/10/28|
HexOrDecimal256 的底层类型是 big.Int,定义该类型实现了对256位比特以内的大整数进行marshal/unmarshal。 实现了 MarshalText 和 UnmarshalText 两个方法,MarshalText 方法将 HexOrDecimal256 编码成16进制的 数,并含有 "0x"前缀;UnmarshalText 方法对给定的字节切片内容进行解码,如果给定的字节切片含有前缀,则把给定 的字节切片看成是16进制的数,然后解析成10进制的大整数,如果不含前缀,则看成是10进制的数。
🚨注意:HexOrDecimal256 作为10进制数,其最大取值是: 115792089237316195423570985008687907853269984665640564039457584007913129639935
func NewHexOrDecimal256 ¶
func NewHexOrDecimal256(x int64) *HexOrDecimal256
NewHexOrDecimal256 ♏ |作者:吴翔宇| 🍁 |日期:2022/10/28|
NewHexOrDecimal256 方法接受一个int64类型的参数x,然后将x转换成一个大整数,最后再将这个大整数通过强制类型转换为 HexOrDecimal256。
func (*HexOrDecimal256) MarshalText ¶
func (h *HexOrDecimal256) MarshalText() ([]byte, error)
MarshalText ♏ |作者:吴翔宇| 🍁 |日期:2022/10/28|
该方法实现了 encoding.TextMarshaler 接口,将数字转换为16进制,然后在前面加上"0x"前缀。
例如:HexOrDecimal256的值等于255,编码后的结果为:[48 120 102 102],字符串形式:"0xff"
该方法返回的第二个参数永远都是nil。
func (*HexOrDecimal256) UnmarshalText ¶
func (h *HexOrDecimal256) UnmarshalText(input []byte) error
UnmarshalText ♏ |作者:吴翔宇| 🍁 |日期:2022/10/28|
该方法实现了 encoding.TextUnmarshaler 接口,该方法将给定的字符串解析成一个大整数,给定的字符串要么含有"0x"或"0X"前 缀,要么不含有,这会决定不同的解析方式:
- 如果给定的字符串含有前缀,则给定的字符串必须满足以下两个条件才能解析成功: - 字符串里除了前缀外,其余字符的取值范围只能在{0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F}里 - 实际上,尽管给的字符串是16进制的,但是解析后得到大整数是10进制形式的,如果解析后的结果需要超过256位比特去存储,则该 方法认为解析失败,默认解析后所能获得的最大整数是: 115792089237316195423570985008687907853269984665640564039457584007913129639935
- 如果给定的字符串不含有前缀,则给定的字符串必须满足以下两个条件才能解析成功: - 字符串里每个字符的取值范围只能在{0 1 2 3 4 5 6 7 8 9}里 - 解码后得到的大整数必须小于115792089237316195423570985008687907853269984665640564039457584007913129639935 给出两个例子: - 输入"0x12a",得到:298 - 输入"123",得到:123
type HexOrDecimal64 ¶
type HexOrDecimal64 uint64
HexOrDecimal64 ♏ |作者:吴翔宇| 🍁 |日期:2022/10/29|
HexOrDecimal64 类型的底层是uint64类型,
func (HexOrDecimal64) MarshalText ¶
func (h HexOrDecimal64) MarshalText() ([]byte, error)
MarshalText ♏ |作者:吴翔宇| 🍁 |日期:2022/10/29|
该方法实现了 encoding.TextMarshaler 接口,实现将10进制数转换成16进制,并在前面加上"0x"前缀。
func (*HexOrDecimal64) UnmarshalText ¶
func (h *HexOrDecimal64) UnmarshalText(input []byte) error
UnmarshalText ♏ |作者:吴翔宇| 🍁 |日期:2022/10/29|
该方法实现了 encoding.TextUnmarshaler 接口,该方法实际上是调用 ParseUint64 方法来把给定的字节切片 数据解析成64位的无符号整数,支持解析含有"0x"或"0X"前缀的16进制数,也支持解析10进制数。
例如:给定的string(input)="0x123",得到整数:291;如果给定的string(input)="123",得到整数:123。