1

i having this error in pragma solidity >=0.7.0 <0.9.0

int256 constant REAL_BITS = 128;
int256 constant REAL_FBITS = 40;
int256 constant REAL_IBITS = REAL_BITS - REAL_FBITS;
int128 constant REAL_ONE = int128(1) << int128(REAL_FBITS);
int128 constant REAL_HALF = REAL_ONE >> int128(1);
int128 constant REAL_TWO = REAL_ONE << int128(1);

errors:

  • Operator << not compatible with types int128 and int128
  • Operator >> not compatible with types int128 and int128
3
  • I'm pretty sure that's normal behavior, you can only bit shift by an unsigned integer
    – Foxxxey
    Aug 5 at 19:14
  • How else could I achieve what I require? Aug 6 at 14:18
  • In your case, why are you using ints at all instead of uints? And for a more general case, see the answer i made.
    – Foxxxey
    Aug 6 at 17:51

2 Answers 2

0

You can't bit shift by a signed integer. One way of working around this would be

function shiftRightBySigned(int128 toShift, int128 shift) public pure returns(uint128 shifted) {
  if(shift < 0) {
    uint256 shiftUint = uint256(int256(shift * (-1)));
    // Shift left to mimic what would happen if we shifted right by a negative number
    shifted = toShift << shiftUint;
  }
  else {
    uint256 shiftUint = uint256(int256(shift));
    shifted = toShift >> shiftUint;
  }
}

And the other way around if you need to shift left.

0

You could also replace all the casting with their literal values:

  int256 constant REAL_BITS = 128;
  int256 constant REAL_FBITS = 40;
  int256 constant REAL_IBITS = REAL_BITS - REAL_FBITS;
  int128 constant REAL_ONE = 1 << 40;
  int128 constant REAL_HALF = REAL_ONE >> 1;
  int128 constant REAL_TWO = REAL_ONE << 1;

This works.

In your example, the compiler is having a hard time solving the types issue. Anyways, when using constant and immutable variables, the compiler will replace them wherever they appear with their literal type. So there is no problem if you use literal types directly as I showed.

Tip:

In solidity, we can make any arithmetic operation with literal numbers, even if they go way beyond their range of value, but at the end we need to fit them in the range we want to use for them.

For example, we could do this:

uint32 n = (2**800 + 1) - 2**800;

As we see, 2 ** 800 goes way beyond the maximum value range that Solidity supports, which is 2 ** 64. But, since we are extracting 2 ** 800, the result is below our expected type in the example which is uint32 and it works fine.

https://docs.soliditylang.org/en/v0.8.15/types.html#rational-and-integer-literals

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.