首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Yul中推送数组中的值

如何在Yul中推送数组中的值
EN

Ethereum用户
提问于 2022-10-20 12:29:31
回答 1查看 165关注 0票数 1

在这个函数中,如何在for循环的末尾推送z值?

代码语言:javascript
复制
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)
                    }
                }
            }
        }
    }
}

我试过这个解决方案,但不起作用

代码语言:javascript
复制
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);
    }
}```
EN

回答 1

Ethereum用户

发布于 2022-10-28 04:56:14

我也在寻找这方面的答案,推到内存数组。现在,我通过在yul中增加内存数组的大小来做到这一点,然后使用solidity为最后一个索引添加一个值。

代码语言:javascript
复制
// 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;

希望这能有所帮助

票数 0
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/137849

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档