在这个函数中,如何在for循环的末尾推送z值?
contract Math {
uint256[] nums;
function fpow(
uint256 x,
uint256 n,
uint256 baseUnit
) internal pure returns (uint256 z) {
assembly {
switch x
case 0 {
switch n
case 0 {
// 0 ** 0 = 1
z := baseUnit
}
default {
// 0 ** n = 0
z := 0
}
}
default {
switch mod(n, 2)
case 0 {
// If n is even, store baseUnit in z for now.
z := baseUnit
}
default {
// If n is odd, store x in z for now.
z := x
}
// Shifting right by 1 is like dividing by 2.
let half := shr(1, baseUnit)
for {
// Shift n right by 1 before looping to halve it.
n := shr(1, n)
} n {
// Shift n right by 1 each iteration to halve it.
n := shr(1, n)
} {
// Revert immediately if x ** 2 would overflow.
// Equivalent to iszero(eq(div(xx, x), x)) here.
if shr(128, x) {
revert(0, 0)
}
// Store x squared.
let xx := mul(x, x)
// Round to the nearest number.
let xxRound := add(xx, half)
// Revert if xx + half overflowed.
if lt(xxRound, xx) {
revert(0, 0)
}
// Set x to scaled xxRound.
x := div(xxRound, baseUnit)
// If n is even:
if mod(n, 2) {
// Compute z * x.
let zx := mul(z, x)
// If z * x overflowed:
if iszero(eq(div(zx, x), z)) {
// Revert if x is non-zero.
if iszero(iszero(x)) {
revert(0, 0)
}
}
// Round to the nearest number.
let zxRound := add(zx, half)
// Revert if zx + half overflowed.
if lt(zxRound, zx) {
revert(0, 0)
}
// Return properly scaled zxRound.
z := div(zxRound, baseUnit)
}
}
}
}
}
}我试过这个解决方案,但不起作用
pragma solidity ^0.8.0;
contract Math {
mapping(uint256 => uint256) nums;
uint256 len = 0;
function fpowWrite(
uint256 x,
uint256 n,
uint256 baseUnit
) public returns (uint256 z) {
assembly {
...
// Shifting right by 1 is like dividing by 2.
let half := shr(1, baseUnit)
let count := 0 // ADDED THIS
for {
// Shift n right by 1 before looping to halve it.
n := shr(1, n)
} n {
// Shift n right by 1 each iteration to halve it.
n := shr(1, n)
} {
...
// Return properly scaled zxRound.
z := div(zxRound, baseUnit)
// ADDED THIS
sstore(count, z)
sstore(add(count, 1), add(count, 1))
count := add(count, 2)
}
}
}
}
}
function getValues() public view returns(uint256[] memory) {
uint256[] memory _nums;
for(uint256 i = 0; i < len; i++) {
_nums[i] = nums[i];
}
return (_nums);
}
function getLen() public view returns (uint256) {
return (len);
}
}```发布于 2022-10-28 04:56:14
我也在寻找这方面的答案,推到内存数组。现在,我通过在yul中增加内存数组的大小来做到这一点,然后使用solidity为最后一个索引添加一个值。
// get index to assign value to
uint i = mem_arr.length;
// increase the size of memory array w/ yul
assembly { mstore(mem_arr, add(mload(mem_arr), 1)) }
// assign value
mem_arr[i] = value;希望这能有所帮助
https://ethereum.stackexchange.com/questions/137849
复制相似问题