Skip to content

Commit

Permalink
Merge pull request ethereum#3958 from meowingtwurtle/fixedPointTypes
Browse files Browse the repository at this point in the history
Types class changes for fixed points
  • Loading branch information
chriseth authored Apr 30, 2018
2 parents 1604a99 + 5423974 commit 9e61b25
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 19 deletions.
28 changes: 9 additions & 19 deletions libsolidity/ast/Types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -627,8 +627,7 @@ bool FixedPointType::isImplicitlyConvertibleTo(Type const& _convertTo) const
bool FixedPointType::isExplicitlyConvertibleTo(Type const& _convertTo) const
{
return _convertTo.category() == category() ||
_convertTo.category() == Category::Integer ||
_convertTo.category() == Category::FixedBytes;
(_convertTo.category() == Category::Integer && !dynamic_cast<IntegerType const&>(_convertTo).isAddress());
}

TypePointer FixedPointType::unaryOperatorResult(Token::Value _operator) const
Expand Down Expand Up @@ -682,33 +681,24 @@ bigint FixedPointType::minIntegerValue() const

TypePointer FixedPointType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const
{
if (
_other->category() != Category::RationalNumber &&
_other->category() != category() &&
_other->category() != Category::Integer
)
return TypePointer();
auto commonType = Type::commonType(shared_from_this(), _other); //might be fixed point or integer
auto commonType = Type::commonType(shared_from_this(), _other);

if (!commonType)
return TypePointer();

// All fixed types can be compared
if (Token::isCompareOp(_operator))
return commonType;
if (Token::isBitOp(_operator) || Token::isBooleanOp(_operator))
if (Token::isBitOp(_operator) || Token::isBooleanOp(_operator) || _operator == Token::Exp)
return TypePointer();
if (auto fixType = dynamic_pointer_cast<FixedPointType const>(commonType))
{
if (Token::Exp == _operator)
return TypePointer();
}
else if (auto intType = dynamic_pointer_cast<IntegerType const>(commonType))
if (intType->isAddress())
return TypePointer();
return commonType;
}

std::shared_ptr<IntegerType> FixedPointType::asIntegerType() const
{
return std::make_shared<IntegerType>(numBits(), isSigned() ? IntegerType::Modifier::Signed : IntegerType::Modifier::Unsigned);
}

tuple<bool, rational> RationalNumberType::parseRational(string const& _value)
{
rational value;
Expand Down Expand Up @@ -1148,7 +1138,7 @@ u256 RationalNumberType::literalValue(Literal const*) const
auto fixed = fixedPointType();
solAssert(fixed, "");
int fractionalDigits = fixed->fractionalDigits();
shiftedValue = (m_value.numerator() / m_value.denominator()) * pow(bigint(10), fractionalDigits);
shiftedValue = m_value.numerator() * pow(bigint(10), fractionalDigits) / m_value.denominator();
}

// we ignore the literal and hope that the type was correctly determined
Expand Down
3 changes: 3 additions & 0 deletions libsolidity/ast/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,9 @@ class FixedPointType: public Type
/// smallest value in general.
bigint minIntegerValue() const;

/// @returns the smallest integer type that can hold this type with fractional parts shifted to integers.
std::shared_ptr<IntegerType> asIntegerType() const;

private:
int m_totalBits;
int m_fractionalDigits;
Expand Down

0 comments on commit 9e61b25

Please sign in to comment.