diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index fe59e76e3..68e600055 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -1224,27 +1224,29 @@ FixedPointType const* RationalNumberType::fixedPointType() const pair RationalNumberType::mantissaExponent() const { - bool negative = (m_value < 0); - int exponent = 0; - rational value = abs(m_value); // We care about the sign later. - rational maxValue = negative ? - rational(bigint(1) << 255, 1): - rational((bigint(1) << 256) - 1, 1); + rational const maxUint = rational((bigint(1) << 256) - 1); + rational const minInt = -rational(bigint(1) << 255); - while (value.denominator() != 1) + bool negative = (m_value < 0); + rational const maxMantissa = (negative ? -minInt : maxUint); + + int exponent = 0; + rational unsignedMantissa = abs(m_value); + while (unsignedMantissa.denominator() != 1) { - value *= 10; - exponent--; + unsignedMantissa *= 10; + --exponent; + if ( - value > rational((bigint(1) << 256) - 1) || - value < rational(-(bigint(1) << 255)) || - exponent < -255 // TODO sane vale? + unsignedMantissa > maxUint || + unsignedMantissa < minInt || + exponent < -255 // TODO: sane value? ) return {nullptr, nullptr}; } return { - TypeProvider::rationalNumber(value), + TypeProvider::rationalNumber(unsignedMantissa), TypeProvider::rationalNumber(-exponent), }; } diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 78bb806f7..9b4567793 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -587,7 +587,12 @@ public: /// @returns true if the value is not an integer. bool isFractional() const { return m_value.denominator() != 1; } - /// TODO document + // TODO: Update if it turns out we do need to support negative numbers here. + /// Tries to decompose a positive rational number into two positive integers - a mantissa and a + /// base-10 exponent, such that the number is equal to `mantissa * 10**-exponent`. + /// @returns Pair of non-null pointers representing the types of the literals corresponding to + /// mantissa and exponent if the resulting mantissa and exponent both fit in 256 bits. + /// A pair of null pointers otherwise. std::pair mantissaExponent() const; /// @returns true if the value is negative.