diff options
author | Daniel Kirchner <daniel@ekpyron.org> | 2018-05-08 01:09:52 +0800 |
---|---|---|
committer | Alex Beregszaszi <alex@rtfs.hu> | 2018-06-12 16:32:19 +0800 |
commit | f33dc92cbd908a6d852368fa30144bda9e8da439 (patch) | |
tree | a8bb2fd5921c71a8c898564a96ec1ee54d206dc6 /libsolidity/ast/Types.cpp | |
parent | 8999a2f375410a29bae46b8e87a70c62036c880d (diff) | |
download | dexon-solidity-f33dc92cbd908a6d852368fa30144bda9e8da439.tar dexon-solidity-f33dc92cbd908a6d852368fa30144bda9e8da439.tar.gz dexon-solidity-f33dc92cbd908a6d852368fa30144bda9e8da439.tar.bz2 dexon-solidity-f33dc92cbd908a6d852368fa30144bda9e8da439.tar.lz dexon-solidity-f33dc92cbd908a6d852368fa30144bda9e8da439.tar.xz dexon-solidity-f33dc92cbd908a6d852368fa30144bda9e8da439.tar.zst dexon-solidity-f33dc92cbd908a6d852368fa30144bda9e8da439.zip |
Use proper SAR for signed right shifts and emulate on pre-constantinople.
Diffstat (limited to 'libsolidity/ast/Types.cpp')
-rw-r--r-- | libsolidity/ast/Types.cpp | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 1e0565c0..94e04b6a 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -1084,9 +1084,16 @@ TypePointer RationalNumberType::binaryOperatorResult(Token::Value _operator, Typ { uint32_t exponent = other.m_value.numerator().convert_to<uint32_t>(); if (exponent > mostSignificantBit(boost::multiprecision::abs(m_value.numerator()))) - value = 0; + value = m_value.numerator() < 0 ? -1 : 0; else - value = rational(m_value.numerator() / boost::multiprecision::pow(bigint(2), exponent), 1); + { + if (m_value.numerator() < 0) + // add 1 to the negative value before dividing to get a result that is strictly too large + // subtract 1 afterwards to round towards negative infinity + value = rational((m_value.numerator() + 1) / boost::multiprecision::pow(bigint(2), exponent) - bigint(1), 1); + else + value = rational(m_value.numerator() / boost::multiprecision::pow(bigint(2), exponent), 1); + } } break; } |