math.big: make big.from_string take a decimal, add big.from_hex_string

pull/7467/head
Delyan Angelov 2020-12-22 09:44:59 +02:00
parent b47daad40d
commit 93c0f503a2
3 changed files with 38 additions and 12 deletions

View File

@ -60,6 +60,7 @@ const (
'vlib/cli/',
'vlib/flag/',
'vlib/gg/gg.v',
'vlib/math/big/',
'vlib/os/',
'vlib/semver/',
'vlib/strings/',

View File

@ -75,26 +75,28 @@ fn C.bignum_isqrt(a &Number, b &Number)
// copy src number to dst number
fn C.bignum_assign(dst &Number, src &Number)
// //////////////////////////////////////////////////////////
// conversion actions to/from big numbers:
// new returns a bignum, initialized to 0
pub fn new() Number {
return Number{}
}
// conversion actions to/from big numbers:
// from_int converts an ordinary int number `i` to big.Number
pub fn from_int(i int) Number {
n := Number{}
C.bignum_from_int(&n, i)
return n
}
// from_u64 converts an ordinary u64 number `u` to big.Number
pub fn from_u64(u u64) Number {
n := Number{}
C.bignum_from_int(&n, u)
return n
}
// Converts a hex string to big.Number.
pub fn from_string(input string) Number {
// from_hex_string converts a hex string to big.Number
pub fn from_hex_string(input string) Number {
mut s := input.trim_prefix('0x')
if s.len == 0 {
s = '0'
@ -106,6 +108,17 @@ pub fn from_string(input string) Number {
return n
}
// from_string converts a decimal string to big.Number
pub fn from_string(input string) Number {
mut n := from_int(0)
for _, c in input {
d := from_int(int(c - `0`))
n = (n * ten) + d
}
return n
}
// .int() converts (a small) big.Number `n` to an ordinary integer.
pub fn (n Number) int() int {
r := C.bignum_to_int(&n)
return r
@ -115,7 +128,7 @@ const (
ten = from_int(10)
)
// Decimal representation for the big unsigned integer number n.
// .str returns a decimal representation of the big unsigned integer number n.
pub fn (n Number) str() string {
if n.is_zero() {
return '0'
@ -131,10 +144,11 @@ pub fn (n Number) str() string {
return digits.reverse().bytestr()
}
// .hexstr returns a hexadecimal representation of the bignum `n`
pub fn (n Number) hexstr() string {
mut buf := [8192]byte{}
// NB: C.bignum_to_string(), returns the HEXADECIMAL representation of the bignum n
C.bignum_to_string(&n, buf, 8192)
// NB: bignum_to_string , returns the HEXADECIMAL representation of the bignum n
s := tos_clone(buf)
if s.len == 0 {
return '0'

View File

@ -78,13 +78,24 @@ fn test_mod() {
}
fn test_from_str() {
assert big.from_string('').hexstr() == '0'
assert big.from_string('1').hexstr() == '1'
assert big.from_string('0').hexstr() == '0'
assert big.from_string('0x123').hexstr() == '123'
assert big.from_string('9870123').str() == '9870123'
assert big.from_string('').str() == '0'
assert big.from_string('0').str() == '0'
assert big.from_string('1').str() == '1'
for i := 1; i < 307; i += 61 {
input := '9'.repeat(i)
out := big.from_string(input).str()
// eprintln('>> i: $i input: $input.str()')
// eprintln('>> i: $i out: $out.str()')
assert input == out
}
}
fn test_from_hex_str() {
assert big.from_hex_string('0x123').hexstr() == '123'
for i in 1 .. 33 {
input := 'e'.repeat(i)
out := big.from_string(input).hexstr()
out := big.from_hex_string(input).hexstr()
assert input == out
}
assert big.from_string('0').hexstr() == '0'
@ -98,7 +109,7 @@ fn test_str() {
assert big.from_u64(4398046511104).str() == '4398046511104'
assert big.from_int(4294967295).str() == '18446744073709551615'
assert big.from_int(-1).str() == '18446744073709551615'
assert big.from_string('e'.repeat(80)).str() ==
assert big.from_hex_string('e'.repeat(80)).str() ==
'1993587900192849410235353592424915306962524220866209251950572167300738410728597846688097947807470'
}