1

Take this code snippet:

function powOfTen(uint256 x) internal pure returns (int256 result) {
    assembly {
        switch x
        case 1 { result := -18 }
    }
}

Which doesn't compile:

ParserError: Literal or identifier expected.
   --> contracts/PRBMath.sol:352:32:
    |
352 |             case 1 { result := -18 }
    |

How can I assign to a negative number in yul?

Paul Razvan Berg
  • 17,902
  • 6
  • 73
  • 143
  • 1
    Is your question "how to assing to negative numbers in yul inside a switch statement" or why do you have such weird switch there :) – Lauri Peltonen Mar 30 '21 at 16:04
  • @LauriPeltonen I guess he wants to test the function quickly, but probably I'm wrong! ;) – alberto Mar 30 '21 at 16:49
  • @LauriPeltonen I didn't know that assignment works differently in switch statements. In fact, I am quite new to yul and assembly. See this Q&A for the full context of why I wanted to use switch. – Paul Razvan Berg Mar 31 '21 at 08:22

2 Answers2

2

That's because you need to use Two's complement representation to use signed integers in yul, since that's the way EVM understand them:

There are some comments about Two's Complement in the Solidity docs:

So, solving your doubt:

-15 is represented as: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1

-3 is represented as: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd

function powOfTen(uint256 x) public pure returns (int256 result) {
    assembly {
        switch x
        case 1 { result := 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1 }
        case 2 { result := 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd }
    }
}

I've modified the function from internal to public if you want to test it on Remix.

alberto
  • 3,343
  • 2
  • 12
  • 21
1

An alternative to @alberto's solution is to use the sub instruction:

function powOfTen(uint256 x) internal pure returns (int256 result) {
    assembly {
        switch x
        case 1 { result := sub(0, 18) }
    }
}

The nice thing about this is that it's cleaner, while still paying the same amount of gas when compiling with the optimizer enabled. Credits to Gitter user @hrkrshnn for telling me about this approach.

Paul Razvan Berg
  • 17,902
  • 6
  • 73
  • 143