首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将Yul翻译成扎实

将Yul翻译成扎实
EN

Ethereum用户
提问于 2022-10-21 15:17:47
回答 1查看 60关注 0票数 0

我有这个Yul功能,为了学习的目的,我正试图逆转到稳固。我对实体函数的结果与原来的函数不同,我不知道我缺少了什么。

最初的Yul函数:

代码语言:javascript
复制
    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
复制
    function fpowSol(
        uint256 x,
        uint256 n,
        uint256 baseUnit
    ) public pure returns (uint256 z) {
        if(x == 0) {
            if(n == 0) {
                return (baseUnit);
            } else {
                return (0);
            }
        }

        if(n % 2 == 0) {
            z = baseUnit;
        } else {
            z = x;
        }

        uint256 half = baseUnit >> 1;

        for(n >>= 1; n > 0; n >>= 1) {
            uint256 xx = x * x;
            if(xx / x != x) { require(false, "xx overvlowed"); }

            uint256 xxRound = xx + half;
            if(xxRound < xx) { require(false, "xxRound overflowed"); }

            x = xxRound / baseUnit;

            if(n % 2 == 0) {
                uint256 zx = z * x;
                require(zx / x == z, "zx overflowed");

                uint256 zxRound = zx + half;
                if(zxRound < zx) { require(false, "zxRound overflowed"); }

                z = zxRound / baseUnit;
            }
        }
        return (z);
    }

你将如何在稳固中重写这个Yul函数?

我从玉到实的翻译有什么不对?

EN

回答 1

Ethereum用户

回答已采纳

发布于 2022-10-21 19:10:06

我之所以不能得到同样的结果,是因为上一次if声明对我有误导作用

代码语言:javascript
复制
                    // If n is even:
                    if mod(n, 2) { ... }

实际上,这不是if(n%0 != 0),实际上是“如果n不是偶数”。

我对yul是新手,所以如果我错了,请纠正我,但是我已经能够得到一致的结果到主函数和我的计算链上。我想这个答案是正确的。

实函数是

代码语言:javascript
复制
    function fpowSol(
        uint256 x,
        uint256 n,
        uint256 baseUnit
    ) public pure returns (uint256 z) {
        if(x == 0) {
            if(n == 0) {
                return (baseUnit);
            } else {
                return (0);
            }
        }

        if(n % 2 == 0) {
            z = baseUnit;
        } else {
            z = x;
        }

        uint256 half = baseUnit >> 1;

        for(n >>= 1; n > 0; n >>= 1) {
            uint256 xx = x * x;
            if(xx / x != x) { require(false, "xx overvlowed"); }

            uint256 xxRound = xx + half;
            if(xxRound < xx) { require(false, "xxRound overflowed"); }

            x = xxRound / baseUnit;

            if(n % 2 != 0) { // THIS HAS CHANGED
                uint256 zx = z * x;
                require(zx / x == z, "zx overflowed");

                uint256 zxRound = zx + half;
                if(zxRound < zx) { require(false, "zxRound overflowed"); }

                z = zxRound / baseUnit;
            }
        }
        return (z);
    }
票数 0
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

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

复制
相关文章

相似问题

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