Merge PR #5428: Add mod, exponentiation for uint
This commit is contained in:
parent
cf4645213d
commit
876beef634
|
@ -76,7 +76,7 @@ if the provided arguments are invalid.
|
|||
`StdTx.Signatures` to get back the array of StdSignatures `[]StdSignature`.
|
||||
* (modules) [\#5299](https://github.com/cosmos/cosmos-sdk/pull/5299) `HandleDoubleSign` along with params `MaxEvidenceAge`
|
||||
and `DoubleSignJailEndTime` have moved from the `x/slashing` module to the `x/evidence` module.
|
||||
* (keys) [\#4941](https://github.com/cosmos/cosmos-sdk/issues/4941) Initializing a new keybase through `NewKeyringFromHomeFlag`, `NewKeyringFromDir`, `NewKeyBaseFromHomeFlag`, `NewKeyBaseFromDir`, or `NewInMemory` functions now accept optional parameters of type `KeybaseOption`. These optional parameters are also added on the keys subcommands functions, which are now public, and allows these options to be set on the commands or ignored to default to previous behavior.
|
||||
* (keys) [\#4941](https://github.com/cosmos/cosmos-sdk/issues/4941) Initializing a new keybase through `NewKeyringFromHomeFlag`, `NewKeyringFromDir`, `NewKeyBaseFromHomeFlag`, `NewKeyBaseFromDir`, or `NewInMemory` functions now accept optional parameters of type `KeybaseOption`. These optional parameters are also added on the keys subcommands functions, which are now public, and allows these options to be set on the commands or ignored to default to previous behavior.
|
||||
* The option introduced in this PR is `WithKeygenFunc` which allows a custom bytes to key implementation to be defined when keys are created.
|
||||
* (simapp) [\#5419](https://github.com/cosmos/cosmos-sdk/pull/5419) simapp/helpers.GenTx() now accepts a gas argument.
|
||||
|
||||
|
@ -213,11 +213,12 @@ to detail this new feature and how state transitions occur.
|
|||
* (docs/spec) All module specs moved into their respective module dir in x/ (i.e. docs/spec/staking -->> x/staking/spec)
|
||||
* (docs/) [\#5379](https://github.com/cosmos/cosmos-sdk/pull/5379) Major documentation refactor, including:
|
||||
* (docs/intro/) Add and improve introduction material for newcomers.
|
||||
* (docs/basics/) Add documentation about basic concepts of the cosmos sdk such as the anatomy of an SDK application, the transaction lifecycle or accounts.
|
||||
* (docs/core/) Add documentation about core conepts of the cosmos sdk such as `baseapp`, `server`, `store`s, `context` and more.
|
||||
* (docs/basics/) Add documentation about basic concepts of the cosmos sdk such as the anatomy of an SDK application, the transaction lifecycle or accounts.
|
||||
* (docs/core/) Add documentation about core conepts of the cosmos sdk such as `baseapp`, `server`, `store`s, `context` and more.
|
||||
* (docs/building-modules/) Add reference documentation on concepts relevant for module developers (`keeper`, `handler`, `messages`, `queries`,...).
|
||||
* (docs/interfaces/) Add documentation on building interfaces for the Cosmos SDK.
|
||||
* Redesigned user interface that features new dynamically generated sidebar, build-time code embedding from GitHub, new homepage as well as many other improvements.
|
||||
* (types) [\#5428](https://github.com/cosmos/cosmos-sdk/pull/5428) Add `Mod` (modulo) method and `RelativePow` (exponentation) function for `Uint`.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
|
|
|
@ -99,6 +99,14 @@ func (u Uint) MulUint64(u2 uint64) (res Uint) { return u.Mul(NewUint(u2)) }
|
|||
// Quo divides Uint with Uint
|
||||
func (u Uint) Quo(u2 Uint) (res Uint) { return NewUintFromBigInt(div(u.i, u2.i)) }
|
||||
|
||||
// Mod returns remainder after dividing with Uint
|
||||
func (u Uint) Mod(u2 Uint) Uint {
|
||||
if u2.IsZero() {
|
||||
panic("division-by-zero")
|
||||
}
|
||||
return Uint{mod(u.i, u2.i)}
|
||||
}
|
||||
|
||||
// Quo divides Uint with uint64
|
||||
func (u Uint) QuoUint64(u2 uint64) Uint { return u.Quo(NewUint(u2)) }
|
||||
|
||||
|
@ -172,3 +180,39 @@ func checkNewUint(i *big.Int) (Uint, error) {
|
|||
}
|
||||
return Uint{i}, nil
|
||||
}
|
||||
|
||||
// RelativePow raises x to the power of n, where x (and the result, z) are scaled by factor b
|
||||
// for example, RelativePow(210, 2, 100) = 441 (2.1^2 = 4.41)
|
||||
func RelativePow(x Uint, n Uint, b Uint) (z Uint) {
|
||||
if x.IsZero() {
|
||||
if n.IsZero() {
|
||||
z = b // 0^0 = 1
|
||||
return
|
||||
}
|
||||
z = ZeroUint() // otherwise 0^a = 0
|
||||
return
|
||||
}
|
||||
|
||||
z = x
|
||||
if n.Mod(NewUint(2)).Equal(ZeroUint()) {
|
||||
z = b
|
||||
}
|
||||
|
||||
halfOfB := b.Quo(NewUint(2))
|
||||
n = n.Quo(NewUint(2))
|
||||
|
||||
for n.GT(ZeroUint()) {
|
||||
xSquared := x.Mul(x)
|
||||
xSquaredRounded := xSquared.Add(halfOfB)
|
||||
|
||||
x = xSquaredRounded.Quo(b)
|
||||
|
||||
if n.Mod(NewUint(2)).Equal(OneUint()) {
|
||||
zx := z.Mul(x)
|
||||
zxRounded := zx.Add(halfOfB)
|
||||
z = zxRounded.Quo(b)
|
||||
}
|
||||
n = n.Quo(NewUint(2))
|
||||
}
|
||||
return z
|
||||
}
|
||||
|
|
|
@ -256,3 +256,22 @@ func TestParseUint(t *testing.T) {
|
|||
func randuint() Uint {
|
||||
return NewUint(rand.Uint64())
|
||||
}
|
||||
|
||||
func TestRelativePow(t *testing.T) {
|
||||
tests := []struct {
|
||||
args []Uint
|
||||
want Uint
|
||||
}{
|
||||
{[]Uint{ZeroUint(), ZeroUint(), OneUint()}, OneUint()},
|
||||
{[]Uint{ZeroUint(), ZeroUint(), NewUint(10)}, NewUint(10)},
|
||||
{[]Uint{ZeroUint(), OneUint(), NewUint(10)}, ZeroUint()},
|
||||
{[]Uint{NewUint(10), NewUint(2), OneUint()}, NewUint(100)},
|
||||
{[]Uint{NewUint(210), NewUint(2), NewUint(100)}, NewUint(441)},
|
||||
{[]Uint{NewUint(2100), NewUint(2), NewUint(1000)}, NewUint(4410)},
|
||||
{[]Uint{NewUint(1000000001547125958), NewUint(600), NewUint(1000000000000000000)}, NewUint(1000000928276004850)},
|
||||
}
|
||||
for i, tc := range tests {
|
||||
res := RelativePow(tc.args[0], tc.args[1], tc.args[2])
|
||||
require.Equal(t, tc.want, res, "unexpected result for test case %d, input: %v, got: %v", i, tc.args, res)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue