mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Allow explicit conversion from rational to fixed if it fits value range.
This commit is contained in:
parent
1e816332f3
commit
28e8f5571b
@ -756,19 +756,31 @@ string FixedPointType::toString(bool) const
|
|||||||
|
|
||||||
bigint FixedPointType::maxIntegerValue() const
|
bigint FixedPointType::maxIntegerValue() const
|
||||||
{
|
{
|
||||||
bigint maxValue = (bigint(1) << (m_totalBits - (isSigned() ? 1 : 0))) - 1;
|
rational max = maxValue();
|
||||||
return maxValue / boost::multiprecision::pow(bigint(10), m_fractionalDigits);
|
return max.numerator() / max.denominator();
|
||||||
}
|
}
|
||||||
|
|
||||||
bigint FixedPointType::minIntegerValue() const
|
bigint FixedPointType::minIntegerValue() const
|
||||||
|
{
|
||||||
|
rational min = minValue();
|
||||||
|
return min.numerator() / min.denominator();
|
||||||
|
}
|
||||||
|
|
||||||
|
rational FixedPointType::maxValue() const
|
||||||
|
{
|
||||||
|
bigint maxValue = (bigint(1) << (m_totalBits - (isSigned() ? 1 : 0))) - 1;
|
||||||
|
return rational(maxValue) / boost::multiprecision::pow(bigint(10), m_fractionalDigits);
|
||||||
|
}
|
||||||
|
|
||||||
|
rational FixedPointType::minValue() const
|
||||||
{
|
{
|
||||||
if (isSigned())
|
if (isSigned())
|
||||||
{
|
{
|
||||||
bigint minValue = -(bigint(1) << (m_totalBits - (isSigned() ? 1 : 0)));
|
bigint minValue = -(bigint(1) << (m_totalBits - 1));
|
||||||
return minValue / boost::multiprecision::pow(bigint(10), m_fractionalDigits);
|
return rational(minValue) / boost::multiprecision::pow(bigint(10), m_fractionalDigits);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return bigint(0);
|
return rational{0};
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeResult FixedPointType::binaryOperatorResult(Token _operator, Type const* _other) const
|
TypeResult FixedPointType::binaryOperatorResult(Token _operator, Type const* _other) const
|
||||||
@ -985,11 +997,24 @@ BoolResult RationalNumberType::isExplicitlyConvertibleTo(Type const& _convertTo)
|
|||||||
else if (category == Category::Integer)
|
else if (category == Category::Integer)
|
||||||
return false;
|
return false;
|
||||||
else if (auto enumType = dynamic_cast<EnumType const*>(&_convertTo))
|
else if (auto enumType = dynamic_cast<EnumType const*>(&_convertTo))
|
||||||
|
{
|
||||||
if (isNegative() || isFractional() || m_value >= enumType->numberOfMembers())
|
if (isNegative() || isFractional() || m_value >= enumType->numberOfMembers())
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
else if (auto fixedPointType = dynamic_cast<FixedPointType const*>(&_convertTo))
|
||||||
|
{
|
||||||
|
if (value() < fixedPointType->minValue())
|
||||||
|
return BoolResult::err("Value is too small.");
|
||||||
|
else if (value() > fixedPointType->maxValue())
|
||||||
|
return BoolResult::err("Value is too large.");
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
Type const* mobType = mobileType();
|
Type const* mobType = mobileType();
|
||||||
return (mobType && mobType->isExplicitlyConvertibleTo(_convertTo));
|
if (!mobType)
|
||||||
|
return false;
|
||||||
|
return mobType->isExplicitlyConvertibleTo(_convertTo);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,6 +529,9 @@ public:
|
|||||||
/// smallest value in general.
|
/// smallest value in general.
|
||||||
bigint minIntegerValue() const;
|
bigint minIntegerValue() const;
|
||||||
|
|
||||||
|
rational maxValue() const;
|
||||||
|
rational minValue() const;
|
||||||
|
|
||||||
/// @returns the smallest integer type that can hold this type with fractional parts shifted to integers.
|
/// @returns the smallest integer type that can hold this type with fractional parts shifted to integers.
|
||||||
IntegerType const* asIntegerType() const;
|
IntegerType const* asIntegerType() const;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user