mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Change fixed point types to have digit count
Signed-off-by: VoR0220 <rj@erisindustries.com>
This commit is contained in:
parent
6d6d4f6907
commit
78769f3b39
@ -196,9 +196,9 @@ TypePointer Type::fromElementaryTypeName(ElementaryTypeNameToken const& _type)
|
|||||||
case Token::UInt:
|
case Token::UInt:
|
||||||
return make_shared<IntegerType>(256, IntegerType::Modifier::Unsigned);
|
return make_shared<IntegerType>(256, IntegerType::Modifier::Unsigned);
|
||||||
case Token::Fixed:
|
case Token::Fixed:
|
||||||
return make_shared<FixedPointType>(128, 128, FixedPointType::Modifier::Signed);
|
return make_shared<FixedPointType>(128, 19, FixedPointType::Modifier::Signed);
|
||||||
case Token::UFixed:
|
case Token::UFixed:
|
||||||
return make_shared<FixedPointType>(128, 128, FixedPointType::Modifier::Unsigned);
|
return make_shared<FixedPointType>(128, 19, FixedPointType::Modifier::Unsigned);
|
||||||
case Token::Byte:
|
case Token::Byte:
|
||||||
return make_shared<FixedBytesType>(1);
|
return make_shared<FixedBytesType>(1);
|
||||||
case Token::Address:
|
case Token::Address:
|
||||||
@ -352,12 +352,13 @@ bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
|||||||
else if (_convertTo.category() == Category::FixedPoint)
|
else if (_convertTo.category() == Category::FixedPoint)
|
||||||
{
|
{
|
||||||
FixedPointType const& convertTo = dynamic_cast<FixedPointType const&>(_convertTo);
|
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;
|
return false;
|
||||||
else if (isSigned())
|
else if (isSigned())
|
||||||
return convertTo.isSigned();
|
return convertTo.isSigned();
|
||||||
else
|
else
|
||||||
return !convertTo.isSigned() || convertTo.integerBits() > m_bits;
|
return !convertTo.isSigned() || convertTo.numBits() > m_bits;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
@ -487,22 +488,20 @@ MemberList::MemberMap IntegerType::nativeMembers(ContractDefinition const*) cons
|
|||||||
return MemberList::MemberMap();
|
return MemberList::MemberMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
FixedPointType::FixedPointType(int _integerBits, int _fractionalBits, FixedPointType::Modifier _modifier):
|
FixedPointType::FixedPointType(int _totalBits, int _fractionalDigits, FixedPointType::Modifier _modifier):
|
||||||
m_integerBits(_integerBits), m_fractionalBits(_fractionalBits), m_modifier(_modifier)
|
m_totalBits(_totalBits), m_fractionalDigits(_fractionalDigits), m_modifier(_modifier)
|
||||||
{
|
{
|
||||||
solAssert(
|
solAssert(
|
||||||
m_integerBits + m_fractionalBits > 0 &&
|
8 <= m_totalBits && m_totalBits <= 256 && m_totalBits % 8 == 0 &&
|
||||||
m_integerBits + m_fractionalBits <= 256 &&
|
0 <= m_fractionalDigits && m_fractionalDigits <= 80,
|
||||||
m_integerBits % 8 == 0 &&
|
|
||||||
m_fractionalBits % 8 == 0,
|
|
||||||
"Invalid bit number(s) for fixed type: " +
|
"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
|
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
|
bool FixedPointType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||||
@ -510,12 +509,10 @@ bool FixedPointType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
|||||||
if (_convertTo.category() == category())
|
if (_convertTo.category() == category())
|
||||||
{
|
{
|
||||||
FixedPointType const& convertTo = dynamic_cast<FixedPointType const&>(_convertTo);
|
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;
|
return false;
|
||||||
else if (isSigned())
|
|
||||||
return convertTo.isSigned();
|
|
||||||
else
|
else
|
||||||
return !convertTo.isSigned() || (convertTo.m_integerBits > m_integerBits);
|
return convertTo.maximumPossibleInteger() >= maximumPossibleInteger();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -527,6 +524,31 @@ bool FixedPointType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
|||||||
_convertTo.category() == Category::FixedBytes;
|
_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
|
TypePointer FixedPointType::unaryOperatorResult(Token::Value _operator) const
|
||||||
{
|
{
|
||||||
// "delete" is ok for all fixed types
|
// "delete" is ok for all fixed types
|
||||||
@ -549,13 +571,13 @@ bool FixedPointType::operator==(Type const& _other) const
|
|||||||
if (_other.category() != category())
|
if (_other.category() != category())
|
||||||
return false;
|
return false;
|
||||||
FixedPointType const& other = dynamic_cast<FixedPointType const&>(_other);
|
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 FixedPointType::toString(bool) const
|
||||||
{
|
{
|
||||||
string prefix = isSigned() ? "fixed" : "ufixed";
|
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
|
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()
|
// We disallow implicit conversion if we would have to truncate (fixedPointType()
|
||||||
// can return a type that requires truncation).
|
// 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);
|
return value.denominator() == 1 && fixed->isImplicitlyConvertibleTo(_convertTo);
|
||||||
}
|
}
|
||||||
|
cout << "could not convert to fixed type" << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (_convertTo.category() == Category::FixedBytes)
|
else if (_convertTo.category() == Category::FixedBytes)
|
||||||
@ -954,9 +979,9 @@ u256 RationalNumberType::literalValue(Literal const*) const
|
|||||||
{
|
{
|
||||||
auto fixed = fixedPointType();
|
auto fixed = fixedPointType();
|
||||||
solAssert(!!fixed, "");
|
solAssert(!!fixed, "");
|
||||||
rational shifted = m_value * (bigint(1) << fixed->fractionalBits());
|
|
||||||
// truncate
|
// 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
|
// 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
|
shared_ptr<FixedPointType const> RationalNumberType::fixedPointType() const
|
||||||
{
|
{
|
||||||
bool negative = (m_value < 0);
|
bool negative = (m_value < 0);
|
||||||
unsigned fractionalBits = 0;
|
unsigned fractionalDigits = 0;
|
||||||
rational value = abs(m_value); // We care about the sign later.
|
rational value = abs(m_value); // We care about the sign later.
|
||||||
rational maxValue = negative ?
|
rational maxValue = negative ?
|
||||||
rational(bigint(1) << 255, 1):
|
rational(bigint(1) << 255, 1):
|
||||||
rational((bigint(1) << 256) - 1, 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;
|
value *= 10;
|
||||||
fractionalBits += 8;
|
fractionalDigits++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value > maxValue)
|
if (value > maxValue)
|
||||||
|
{
|
||||||
|
cout << "value > maxValue" << endl;
|
||||||
return shared_ptr<FixedPointType const>();
|
return shared_ptr<FixedPointType const>();
|
||||||
|
}
|
||||||
// u256(v) is the actual value that will be put on the stack
|
// u256(v) is the actual value that will be put on the stack
|
||||||
// From here on, very similar to integerType()
|
// From here on, very similar to integerType()
|
||||||
bigint v = value.numerator() / value.denominator();
|
bigint v = value.numerator() / value.denominator();
|
||||||
|
cout << "Big int: " << u256(v) << endl;
|
||||||
if (negative)
|
if (negative)
|
||||||
// modify value to satisfy bit requirements for negative numbers:
|
// modify value to satisfy bit requirements for negative numbers:
|
||||||
// add one bit for sign and decrement because negative numbers can be larger
|
// 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))
|
if (v > u256(-1))
|
||||||
return shared_ptr<FixedPointType const>();
|
return shared_ptr<FixedPointType const>();
|
||||||
|
|
||||||
unsigned totalBits = bytesRequired(v) * 8;
|
unsigned totalBits = max(bytesRequired(v), 1u) * 8;
|
||||||
solAssert(totalBits <= 256, "");
|
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>(
|
return make_shared<FixedPointType>(
|
||||||
integerBits, fractionalBits,
|
totalBits, fractionalDigits,
|
||||||
negative ? FixedPointType::Modifier::Signed : FixedPointType::Modifier::Unsigned
|
negative ? FixedPointType::Modifier::Signed : FixedPointType::Modifier::Unsigned
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -321,6 +321,10 @@ public:
|
|||||||
int numBits() const { return m_bits; }
|
int numBits() const { return m_bits; }
|
||||||
bool isAddress() const { return m_modifier == Modifier::Address; }
|
bool isAddress() const { return m_modifier == Modifier::Address; }
|
||||||
bool isSigned() const { return m_modifier == Modifier::Signed; }
|
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 minValue() const;
|
||||||
bigint maxValue() const;
|
bigint maxValue() const;
|
||||||
@ -342,7 +346,7 @@ public:
|
|||||||
};
|
};
|
||||||
virtual Category category() const override { return Category::FixedPoint; }
|
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 std::string identifier() const override;
|
||||||
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
@ -352,8 +356,8 @@ public:
|
|||||||
|
|
||||||
virtual bool operator==(Type const& _other) const override;
|
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 calldataEncodedSize(bool _padded = true) const override { return _padded ? 32 : m_totalBits / 8; }
|
||||||
virtual unsigned storageBytes() const override { return (m_integerBits + m_fractionalBits) / 8; }
|
virtual unsigned storageBytes() const override { return m_totalBits / 8; }
|
||||||
virtual bool isValueType() const override { return true; }
|
virtual bool isValueType() const override { return true; }
|
||||||
|
|
||||||
virtual std::string toString(bool _short) const override;
|
virtual std::string toString(bool _short) const override;
|
||||||
@ -361,14 +365,17 @@ public:
|
|||||||
virtual TypePointer encodingType() const override { return shared_from_this(); }
|
virtual TypePointer encodingType() const override { return shared_from_this(); }
|
||||||
virtual TypePointer interfaceType(bool) 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 numBits() const { return m_totalBits; }
|
||||||
int integerBits() const { return m_integerBits; }
|
int fractionalDigits() const { return m_fractionalDigits; }
|
||||||
int fractionalBits() const { return m_fractionalBits; }
|
|
||||||
bool isSigned() const { return m_modifier == Modifier::Signed; }
|
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:
|
private:
|
||||||
int m_integerBits;
|
int m_totalBits;
|
||||||
int m_fractionalBits;
|
int m_fractionalDigits;
|
||||||
Modifier m_modifier;
|
Modifier m_modifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -504,7 +504,7 @@ void CompilerUtils::convertType(
|
|||||||
//shift all integer bits onto the left side of the fixed type
|
//shift all integer bits onto the left side of the fixed type
|
||||||
FixedPointType const& targetFixedPointType = dynamic_cast<FixedPointType const&>(_targetType);
|
FixedPointType const& targetFixedPointType = dynamic_cast<FixedPointType const&>(_targetType);
|
||||||
if (auto typeOnStack = dynamic_cast<IntegerType const*>(&_typeOnStack))
|
if (auto typeOnStack = dynamic_cast<IntegerType const*>(&_typeOnStack))
|
||||||
if (targetFixedPointType.integerBits() > typeOnStack->numBits())
|
if (targetFixedPointType.numBits() > typeOnStack->numBits())
|
||||||
cleanHigherOrderBits(*typeOnStack);
|
cleanHigherOrderBits(*typeOnStack);
|
||||||
solUnimplemented("Not yet implemented - FixedPointType.");
|
solUnimplemented("Not yet implemented - FixedPointType.");
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ void ElementaryTypeNameToken::assertDetails(Token::Value _baseType, unsigned con
|
|||||||
else if (_baseType == Token::UFixedMxN || _baseType == Token::FixedMxN)
|
else if (_baseType == Token::UFixedMxN || _baseType == Token::FixedMxN)
|
||||||
{
|
{
|
||||||
solAssert(
|
solAssert(
|
||||||
_first + _second <= 256 && _first % 8 == 0 && _second % 8 == 0,
|
_first <= 256 && _first % 8 == 0 && _second >= 0 && _second <= 80,
|
||||||
"No elementary type " + string(Token::toString(_baseType)) + to_string(_first) + "x" + to_string(_second) + "."
|
"No elementary type " + string(Token::toString(_baseType)) + to_string(_first) + "x" + to_string(_second) + "."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -157,12 +157,8 @@ tuple<Token::Value, unsigned int, unsigned int> Token::fromIdentifierOrKeyword(s
|
|||||||
) {
|
) {
|
||||||
int n = parseSize(positionX + 1, _literal.end());
|
int n = parseSize(positionX + 1, _literal.end());
|
||||||
if (
|
if (
|
||||||
0 <= m && m <= 256 &&
|
8 <= m && m <= 256 && m % 8 == 0 &&
|
||||||
8 <= n && n <= 256 &&
|
0 <= n && n <= 80
|
||||||
m + n > 0 &&
|
|
||||||
m + n <= 256 &&
|
|
||||||
m % 8 == 0 &&
|
|
||||||
n % 8 == 0
|
|
||||||
) {
|
) {
|
||||||
if (keyword == Token::UFixed)
|
if (keyword == Token::UFixed)
|
||||||
return make_tuple(Token::UFixedMxN, m, n);
|
return make_tuple(Token::UFixedMxN, m, n);
|
||||||
|
@ -4145,20 +4145,8 @@ BOOST_AUTO_TEST_CASE(rational_unary_operation)
|
|||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract test {
|
contract test {
|
||||||
function f() {
|
function f() {
|
||||||
ufixed8x16 a = 3.25;
|
ufixed16x2 a = +3.25;
|
||||||
fixed8x16 b = -3.25;
|
fixed16x2 b = -3.25;
|
||||||
a;
|
|
||||||
b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
|
||||||
text = R"(
|
|
||||||
contract test {
|
|
||||||
function f() {
|
|
||||||
ufixed8x16 a = +3.25;
|
|
||||||
fixed8x16 b = -3.25;
|
|
||||||
a; b;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
@ -4179,11 +4167,10 @@ BOOST_AUTO_TEST_CASE(leading_zero_rationals_convert)
|
|||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract A {
|
contract A {
|
||||||
function f() {
|
function f() {
|
||||||
ufixed0x8 a = 0.5;
|
ufixed16x8 a = 0.5;
|
||||||
ufixed0x56 b = 0.0000000000000006661338147750939242541790008544921875;
|
ufixed256x56 b = 0.0000000000000006661338147750939242541790008544921875;
|
||||||
fixed0x8 c = -0.5;
|
fixed16x8 c = -0.5;
|
||||||
fixed0x56 d = -0.0000000000000006661338147750939242541790008544921875;
|
fixed256x56 d = -0.0000000000000006661338147750939242541790008544921875;
|
||||||
a; b; c; d;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
@ -4195,13 +4182,25 @@ BOOST_AUTO_TEST_CASE(size_capabilities_of_fixed_point_types)
|
|||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract test {
|
contract test {
|
||||||
function f() {
|
function f() {
|
||||||
ufixed248x8 a = 123456781234567979695948382928485849359686494864095409282048094275023098123.5;
|
ufixed256x1 a = 123456781234567979695948382928485849359686494864095409282048094275023098123.5;
|
||||||
ufixed0x256 b = 0.920890746623327805482905058466021565416131529487595827354393978494366605267637829135688384325135165352082715782143655824815685807141335814463015972119819459298455224338812271036061391763384038070334798471324635050876128428143374549108557403087615966796875;
|
ufixed256x77 b = 0.920890746623327805482905058466021565416131529487595827354393978494366605267637;
|
||||||
ufixed0x256 c = 0.0000000000015198847363997979984922685411315294875958273543939784943666052676464653042434787697605517039455161817147718251801220885263595179331845639229818863564267318422845592626219390573301877339317935702714669975697814319204326238832436501979827880859375;
|
ufixed224x78 c = 0.000000000001519884736399797998492268541131529487595827354393978494366605267646;
|
||||||
fixed248x8 d = -123456781234567979695948382928485849359686494864095409282048094275023098123.5;
|
fixed256x1 d = -123456781234567979695948382928485849359686494864095409282048094275023098123.5;
|
||||||
fixed0x256 e = -0.93322335481643744342575580035176794825198893968114429702091846411734101080123092162893656820177312738451291806995868682861328125;
|
fixed256x76 e = -0.93322335481643744342575580035176794825198893968114429702091846411734101080123;
|
||||||
fixed0x256 g = -0.00011788606643744342575580035176794825198893968114429702091846411734101080123092162893656820177312738451291806995868682861328125;
|
fixed256x79 g = -0.0001178860664374434257558003517679482519889396811442970209184641173410108012309;
|
||||||
a; b; c; d; e; g;
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
CHECK_SUCCESS(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(zero_handling)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
contract test {
|
||||||
|
function f() {
|
||||||
|
fixed16x8 a = 0;
|
||||||
|
ufixed8x8 b = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
@ -4226,7 +4225,7 @@ BOOST_AUTO_TEST_CASE(fixed_type_invalid_implicit_conversion_lost_data)
|
|||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract test {
|
contract test {
|
||||||
function f() {
|
function f() {
|
||||||
ufixed0x256 a = 1/3;
|
ufixed256x1 a = 1/3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
@ -4238,10 +4237,9 @@ BOOST_AUTO_TEST_CASE(fixed_type_valid_explicit_conversions)
|
|||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract test {
|
contract test {
|
||||||
function f() {
|
function f() {
|
||||||
ufixed0x256 a = ufixed0x256(1/3);
|
ufixed256x80 a = ufixed256x80(1/3);
|
||||||
ufixed0x248 b = ufixed0x248(1/3);
|
ufixed248x80 b = ufixed248x80(1/3);
|
||||||
ufixed0x8 c = ufixed0x8(1/3);
|
ufixed8x1 c = ufixed8x1(1/3);
|
||||||
a; b; c;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
@ -4260,7 +4258,7 @@ BOOST_AUTO_TEST_CASE(invalid_array_declaration_with_rational)
|
|||||||
BOOST_CHECK(!success(text));
|
BOOST_CHECK(!success(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(invalid_array_declaration_with_fixed_type)
|
BOOST_AUTO_TEST_CASE(invalid_array_declaration_with_signed_fixed_type)
|
||||||
{
|
{
|
||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract test {
|
contract test {
|
||||||
@ -4272,6 +4270,18 @@ BOOST_AUTO_TEST_CASE(invalid_array_declaration_with_fixed_type)
|
|||||||
BOOST_CHECK(!success(text));
|
BOOST_CHECK(!success(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(invalid_array_declaration_with_unsigned_fixed_type)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
contract test {
|
||||||
|
function f() {
|
||||||
|
uint[ufixed(3.5)] a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
BOOST_CHECK(!success(text));
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(rational_to_bytes_implicit_conversion)
|
BOOST_AUTO_TEST_CASE(rational_to_bytes_implicit_conversion)
|
||||||
{
|
{
|
||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
@ -4301,7 +4311,7 @@ BOOST_AUTO_TEST_CASE(mapping_with_fixed_literal)
|
|||||||
{
|
{
|
||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract test {
|
contract test {
|
||||||
mapping(ufixed8x248 => string) fixedString;
|
mapping(ufixed8x1 => string) fixedString;
|
||||||
function f() {
|
function f() {
|
||||||
fixedString[0.5] = "Half";
|
fixedString[0.5] = "Half";
|
||||||
}
|
}
|
||||||
@ -4341,7 +4351,7 @@ BOOST_AUTO_TEST_CASE(inline_array_rationals)
|
|||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract test {
|
contract test {
|
||||||
function f() {
|
function f() {
|
||||||
ufixed8x8[4] memory a = [3.5, 4.125, 2.5, 4.0];
|
ufixed16x3[4] memory a = [3.5, 4.125, 2.5, 4.0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
@ -4368,10 +4378,10 @@ BOOST_AUTO_TEST_CASE(rational_to_fixed_literal_expression)
|
|||||||
function f() {
|
function f() {
|
||||||
ufixed8x8 a = 3.5 * 3;
|
ufixed8x8 a = 3.5 * 3;
|
||||||
ufixed8x8 b = 4 - 2.5;
|
ufixed8x8 b = 4 - 2.5;
|
||||||
ufixed8x8 c = 11 / 4;
|
ufixed16x8 c = 11 / 4;
|
||||||
ufixed16x240 d = 599 + 0.21875;
|
ufixed240x5 d = 599 + 0.21875;
|
||||||
ufixed8x248 e = ufixed8x248(35.245 % 12.9);
|
ufixed256x80 e = ufixed256x80(35.245 % 12.9);
|
||||||
ufixed8x248 f = ufixed8x248(1.2 % 2);
|
ufixed256x80 f = ufixed256x80(1.2 % 2);
|
||||||
fixed g = 2 ** -2;
|
fixed g = 2 ** -2;
|
||||||
a; b; c; d; e; f; g;
|
a; b; c; d; e; f; g;
|
||||||
}
|
}
|
||||||
@ -4380,7 +4390,7 @@ BOOST_AUTO_TEST_CASE(rational_to_fixed_literal_expression)
|
|||||||
CHECK_SUCCESS(text);
|
CHECK_SUCCESS(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(rational_as_exponent_value_neg_decimal)
|
BOOST_AUTO_TEST_CASE(rational_as_exponent_value_signed)
|
||||||
{
|
{
|
||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract test {
|
contract test {
|
||||||
@ -4392,7 +4402,7 @@ BOOST_AUTO_TEST_CASE(rational_as_exponent_value_neg_decimal)
|
|||||||
BOOST_CHECK(!success(text));
|
BOOST_CHECK(!success(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(rational_as_exponent_value_pos_decimal)
|
BOOST_AUTO_TEST_CASE(rational_as_exponent_value_unsigned)
|
||||||
{
|
{
|
||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract test {
|
contract test {
|
||||||
@ -4564,20 +4574,6 @@ BOOST_AUTO_TEST_CASE(rational_bitand_binary_operation)
|
|||||||
BOOST_CHECK(!success(text));
|
BOOST_CHECK(!success(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(zero_handling)
|
|
||||||
{
|
|
||||||
char const* text = R"(
|
|
||||||
contract test {
|
|
||||||
function f() {
|
|
||||||
fixed8x8 a = 0;
|
|
||||||
ufixed8x8 b = 0;
|
|
||||||
a; b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
CHECK_SUCCESS(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(missing_bool_conversion)
|
BOOST_AUTO_TEST_CASE(missing_bool_conversion)
|
||||||
{
|
{
|
||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
|
Loading…
Reference in New Issue
Block a user