diff options
author | VoR0220 <rj@erisindustries.com> | 2016-12-23 02:20:03 +0800 |
---|---|---|
committer | Alex Beregszaszi <alex@rtfs.hu> | 2017-07-20 04:49:01 +0800 |
commit | 78769f3b39bccbfa02edec302a02377e8fa08a8d (patch) | |
tree | a96666346bbc2abf3d2ed8f331b472b2f90fb2a1 /libsolidity/ast | |
parent | 6d6d4f69078a6417e1cfb89942f7df2264d89987 (diff) | |
download | dexon-solidity-78769f3b39bccbfa02edec302a02377e8fa08a8d.tar.gz dexon-solidity-78769f3b39bccbfa02edec302a02377e8fa08a8d.tar.zst dexon-solidity-78769f3b39bccbfa02edec302a02377e8fa08a8d.zip |
Change fixed point types to have digit count
Signed-off-by: VoR0220 <rj@erisindustries.com>
Diffstat (limited to 'libsolidity/ast')
-rw-r--r-- | libsolidity/ast/Types.cpp | 101 | ||||
-rw-r--r-- | libsolidity/ast/Types.h | 23 |
2 files changed, 73 insertions, 51 deletions
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 76bfb1a8..14e948cc 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -196,9 +196,9 @@ TypePointer Type::fromElementaryTypeName(ElementaryTypeNameToken const& _type) case Token::UInt: return make_shared<IntegerType>(256, IntegerType::Modifier::Unsigned); case Token::Fixed: - return make_shared<FixedPointType>(128, 128, FixedPointType::Modifier::Signed); + return make_shared<FixedPointType>(128, 19, FixedPointType::Modifier::Signed); case Token::UFixed: - return make_shared<FixedPointType>(128, 128, FixedPointType::Modifier::Unsigned); + return make_shared<FixedPointType>(128, 19, FixedPointType::Modifier::Unsigned); case Token::Byte: return make_shared<FixedBytesType>(1); case Token::Address: @@ -352,12 +352,13 @@ bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const else if (_convertTo.category() == Category::FixedPoint) { FixedPointType const& convertTo = dynamic_cast<FixedPointType const&>(_convertTo); - if (convertTo.integerBits() < m_bits || isAddress()) + + if (((u256(1) << m_bits) <= convertTo.numBits() && convertTo.fractionalDigits() == 0) || isAddress()) return false; else if (isSigned()) return convertTo.isSigned(); else - return !convertTo.isSigned() || convertTo.integerBits() > m_bits; + return !convertTo.isSigned() || convertTo.numBits() > m_bits; } else return false; @@ -487,22 +488,20 @@ MemberList::MemberMap IntegerType::nativeMembers(ContractDefinition const*) cons return MemberList::MemberMap(); } -FixedPointType::FixedPointType(int _integerBits, int _fractionalBits, FixedPointType::Modifier _modifier): - m_integerBits(_integerBits), m_fractionalBits(_fractionalBits), m_modifier(_modifier) +FixedPointType::FixedPointType(int _totalBits, int _fractionalDigits, FixedPointType::Modifier _modifier): + m_totalBits(_totalBits), m_fractionalDigits(_fractionalDigits), m_modifier(_modifier) { solAssert( - m_integerBits + m_fractionalBits > 0 && - m_integerBits + m_fractionalBits <= 256 && - m_integerBits % 8 == 0 && - m_fractionalBits % 8 == 0, + 8 <= m_totalBits && m_totalBits <= 256 && m_totalBits % 8 == 0 && + 0 <= m_fractionalDigits && m_fractionalDigits <= 80, "Invalid bit number(s) for fixed type: " + - dev::toString(_integerBits) + "x" + dev::toString(_fractionalBits) - ); + dev::toString(_totalBits) + "x" + dev::toString(_fractionalDigits) + ); } string FixedPointType::identifier() const { - return "t_" + string(isSigned() ? "" : "u") + "fixed" + std::to_string(integerBits()) + "x" + std::to_string(fractionalBits()); + return "t_" + string(isSigned() ? "" : "u") + "fixed" + std::to_string(numBits()) + "x" + std::to_string(fractionalDigits()); } bool FixedPointType::isImplicitlyConvertibleTo(Type const& _convertTo) const @@ -510,12 +509,10 @@ bool FixedPointType::isImplicitlyConvertibleTo(Type const& _convertTo) const if (_convertTo.category() == category()) { FixedPointType const& convertTo = dynamic_cast<FixedPointType const&>(_convertTo); - if (convertTo.m_integerBits < m_integerBits || convertTo.m_fractionalBits < m_fractionalBits) + if (convertTo.numBits() < m_totalBits || convertTo.fractionalDigits() < m_fractionalDigits) return false; - else if (isSigned()) - return convertTo.isSigned(); else - return !convertTo.isSigned() || (convertTo.m_integerBits > m_integerBits); + return convertTo.maximumPossibleInteger() >= maximumPossibleInteger(); } return false; } @@ -527,6 +524,31 @@ bool FixedPointType::isExplicitlyConvertibleTo(Type const& _convertTo) const _convertTo.category() == Category::FixedBytes; } +/*bool FixedPointType::canHoldInteger(unsigned const _bits, bool const _signed) const +{ + // If fixed type has 200 bits and 2 fractional digits, integer has 8 bits, then conversion is possible. + // Write helper function that returns max integer number, not necessarily the bits. + // 2^m_bits <= integer + + // REMINDER: The below was a work in progress until better solution thought up, see below: + // add min and max number functions to integer and fixed types, use them when converting types. + if (_signed && isSigned()) + { + u256 maxInteger = (u256(1) << _bits) - 1; + u256 maxFixedInteger = u256(((u256(1) << numBits()) - 1) / (pow(bigint(10), decimalDigits()))); + } + else if (_signed && !isSigned()) + { + + } + else + { + u256 maxInteger = (u256(1) << _bits) - 1; + u256 maxFixedInteger = u256(((u256(1) << numBits()) - 1) / (pow(bigint(10), decimalDigits()))); + return maxInteger <= maxFixedInteger; + } +}*/ + TypePointer FixedPointType::unaryOperatorResult(Token::Value _operator) const { // "delete" is ok for all fixed types @@ -549,13 +571,13 @@ bool FixedPointType::operator==(Type const& _other) const if (_other.category() != category()) return false; FixedPointType const& other = dynamic_cast<FixedPointType const&>(_other); - return other.m_integerBits == m_integerBits && other.m_fractionalBits == m_fractionalBits && other.m_modifier == m_modifier; + return other.m_totalBits == m_totalBits && other.m_fractionalDigits == m_fractionalDigits && other.m_modifier == m_modifier; } string FixedPointType::toString(bool) const { string prefix = isSigned() ? "fixed" : "ufixed"; - return prefix + dev::toString(m_integerBits) + "x" + dev::toString(m_fractionalBits); + return prefix + dev::toString(m_totalBits) + "x" + dev::toString(m_fractionalDigits); } TypePointer FixedPointType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const @@ -746,9 +768,12 @@ bool RationalNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const { // We disallow implicit conversion if we would have to truncate (fixedPointType() // can return a type that requires truncation). - rational value = m_value * (bigint(1) << fixed->fractionalBits()); + rational value = m_value * boost::multiprecision::pow(bigint(10), fixed->fractionalDigits()); + cout << "value denominator: " << value.denominator() << endl; + cout << "value: " << value << endl; return value.denominator() == 1 && fixed->isImplicitlyConvertibleTo(_convertTo); } + cout << "could not convert to fixed type" << endl; return false; } else if (_convertTo.category() == Category::FixedBytes) @@ -954,9 +979,9 @@ u256 RationalNumberType::literalValue(Literal const*) const { auto fixed = fixedPointType(); solAssert(!!fixed, ""); - rational shifted = m_value * (bigint(1) << fixed->fractionalBits()); // truncate - shiftedValue = shifted.numerator() / shifted.denominator(); + shiftedValue = m_value.numerator() / m_value.denominator(); + cout << "Shifted value: " << shiftedValue << endl; } // we ignore the literal and hope that the type was correctly determined @@ -997,23 +1022,27 @@ shared_ptr<IntegerType const> RationalNumberType::integerType() const shared_ptr<FixedPointType const> RationalNumberType::fixedPointType() const { bool negative = (m_value < 0); - unsigned fractionalBits = 0; + unsigned fractionalDigits = 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); - while (value * 0x100 <= maxValue && value.denominator() != 1 && fractionalBits < 256) + while (value * 10 <= maxValue && value.denominator() != 1 && fractionalDigits < 80) { - value *= 0x100; - fractionalBits += 8; + value *= 10; + fractionalDigits++; } if (value > maxValue) + { + cout << "value > maxValue" << endl; return shared_ptr<FixedPointType const>(); + } // u256(v) is the actual value that will be put on the stack // From here on, very similar to integerType() bigint v = value.numerator() / value.denominator(); + cout << "Big int: " << u256(v) << endl; if (negative) // modify value to satisfy bit requirements for negative numbers: // add one bit for sign and decrement because negative numbers can be larger @@ -1022,26 +1051,12 @@ shared_ptr<FixedPointType const> RationalNumberType::fixedPointType() const if (v > u256(-1)) return shared_ptr<FixedPointType const>(); - unsigned totalBits = bytesRequired(v) * 8; + unsigned totalBits = max(bytesRequired(v), 1u) * 8; solAssert(totalBits <= 256, ""); - unsigned integerBits = totalBits >= fractionalBits ? totalBits - fractionalBits : 0; - // Special case: Numbers between -1 and 0 have their sign bit in the fractional part. - if (negative && abs(m_value) < 1 && totalBits > fractionalBits) - { - fractionalBits += 8; - integerBits = 0; - } - - if (integerBits > 256 || fractionalBits > 256 || fractionalBits + integerBits > 256) - return shared_ptr<FixedPointType const>(); - if (integerBits == 0 && fractionalBits == 0) - { - integerBits = 0; - fractionalBits = 8; - } + cout << "rational turned into " << (negative ? "fixed" : "ufixed") << totalBits << "x" << fractionalDigits << endl; return make_shared<FixedPointType>( - integerBits, fractionalBits, + totalBits, fractionalDigits, negative ? FixedPointType::Modifier::Signed : FixedPointType::Modifier::Unsigned ); } diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index c24cc11a..d5ef343a 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -321,6 +321,10 @@ public: int numBits() const { return m_bits; } bool isAddress() const { return m_modifier == Modifier::Address; } bool isSigned() const { return m_modifier == Modifier::Signed; } + u256 maximumPossibleInteger() const { return isSigned() ? + u256((u256(1) << m_bits) - 1): + u256((u256(1) << m_bits)); + } bigint minValue() const; bigint maxValue() const; @@ -342,7 +346,7 @@ public: }; virtual Category category() const override { return Category::FixedPoint; } - explicit FixedPointType(int _integerBits, int _fractionalBits, Modifier _modifier = Modifier::Unsigned); + explicit FixedPointType(int _totalBits, int _fractionalDigits, Modifier _modifier = Modifier::Unsigned); virtual std::string identifier() const override; virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; @@ -352,8 +356,8 @@ public: virtual bool operator==(Type const& _other) const override; - virtual unsigned calldataEncodedSize(bool _padded = true) const override { return _padded ? 32 : (m_integerBits + m_fractionalBits) / 8; } - virtual unsigned storageBytes() const override { return (m_integerBits + m_fractionalBits) / 8; } + virtual unsigned calldataEncodedSize(bool _padded = true) const override { return _padded ? 32 : m_totalBits / 8; } + virtual unsigned storageBytes() const override { return m_totalBits / 8; } virtual bool isValueType() const override { return true; } virtual std::string toString(bool _short) const override; @@ -361,14 +365,17 @@ public: virtual TypePointer encodingType() const override { return shared_from_this(); } virtual TypePointer interfaceType(bool) const override { return shared_from_this(); } - int numBits() const { return m_integerBits + m_fractionalBits; } - int integerBits() const { return m_integerBits; } - int fractionalBits() const { return m_fractionalBits; } + int numBits() const { return m_totalBits; } + int fractionalDigits() const { return m_fractionalDigits; } bool isSigned() const { return m_modifier == Modifier::Signed; } + u256 maximumPossibleInteger() const { return isSigned() ? + u256(((u256(1) << m_totalBits) - 1) / (pow(bigint(10), m_fractionalDigits))): + u256(((u256(1) << m_totalBits)) / (pow(bigint(10), m_fractionalDigits))); + } private: - int m_integerBits; - int m_fractionalBits; + int m_totalBits; + int m_fractionalDigits; Modifier m_modifier; }; |