mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
added bytes conversion tests, resolved that, converted to binary scaling, refactored the find algo to prevent large numbers and take into account integer bytes
think we're good on solidity type name resolution now removed couts updates to documentation and more removed couts along with literal value implementation forgot semicolons
This commit is contained in:
parent
f0ea817580
commit
82039b732e
@ -362,7 +362,6 @@ MemberList::MemberMap IntegerType::nativeMembers(ContractDefinition const*) cons
|
|||||||
FixedPointType::FixedPointType(int _integerBits, int _fractionalBits, FixedPointType::Modifier _modifier):
|
FixedPointType::FixedPointType(int _integerBits, int _fractionalBits, FixedPointType::Modifier _modifier):
|
||||||
m_integerBits(_integerBits), m_fractionalBits(_fractionalBits), m_modifier(_modifier)
|
m_integerBits(_integerBits), m_fractionalBits(_fractionalBits), m_modifier(_modifier)
|
||||||
{
|
{
|
||||||
cout << "FIXED POINT CONSTRUCTOR: " << _integerBits << "x" << _fractionalBits << endl;
|
|
||||||
solAssert(
|
solAssert(
|
||||||
m_integerBits + m_fractionalBits > 0 &&
|
m_integerBits + m_fractionalBits > 0 &&
|
||||||
m_integerBits + m_fractionalBits <= 256 &&
|
m_integerBits + m_fractionalBits <= 256 &&
|
||||||
@ -572,14 +571,6 @@ bool RationalNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (_convertTo.category() == Category::FixedPoint)
|
else if (_convertTo.category() == Category::FixedPoint)
|
||||||
{
|
|
||||||
cout << "IMPLICIT CONVERSION" << endl;
|
|
||||||
if (fixedPointType() && fixedPointType()->isImplicitlyConvertibleTo(_convertTo))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (_convertTo.category() == Category::FixedPoint)
|
|
||||||
{
|
{
|
||||||
if (fixedPointType() && fixedPointType()->isImplicitlyConvertibleTo(_convertTo))
|
if (fixedPointType() && fixedPointType()->isImplicitlyConvertibleTo(_convertTo))
|
||||||
return true;
|
return true;
|
||||||
@ -588,7 +579,10 @@ bool RationalNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
|||||||
else if (_convertTo.category() == Category::FixedBytes)
|
else if (_convertTo.category() == Category::FixedBytes)
|
||||||
{
|
{
|
||||||
FixedBytesType const& fixedBytes = dynamic_cast<FixedBytesType const&>(_convertTo);
|
FixedBytesType const& fixedBytes = dynamic_cast<FixedBytesType const&>(_convertTo);
|
||||||
return fixedBytes.numBytes() * 8 >= integerType()->numBits();
|
if (m_value.denominator() == 1)
|
||||||
|
return fixedBytes.numBytes() * 8 >= integerType()->numBits();
|
||||||
|
else
|
||||||
|
return fixedBytes.numBytes() * 8 >= fixedPointType()->numBits();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -600,7 +594,6 @@ bool RationalNumberType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
|||||||
TypePointer intType = integerType();
|
TypePointer intType = integerType();
|
||||||
return intType && intType->isExplicitlyConvertibleTo(_convertTo);
|
return intType && intType->isExplicitlyConvertibleTo(_convertTo);
|
||||||
}
|
}
|
||||||
cout << "EXPLICIT CONVERSION" << endl;
|
|
||||||
TypePointer fixType = fixedPointType();
|
TypePointer fixType = fixedPointType();
|
||||||
return fixType && fixType->isExplicitlyConvertibleTo(_convertTo);
|
return fixType && fixType->isExplicitlyConvertibleTo(_convertTo);
|
||||||
}
|
}
|
||||||
@ -612,7 +605,7 @@ TypePointer RationalNumberType::unaryOperatorResult(Token::Value _operator) cons
|
|||||||
{
|
{
|
||||||
case Token::BitNot:
|
case Token::BitNot:
|
||||||
if(m_value.denominator() != 1)
|
if(m_value.denominator() != 1)
|
||||||
BOOST_THROW_EXCEPTION(Error(Error::Type::TypeError) << errinfo_comment("Cannot perform bit operations on non integer fixed type."));
|
return TypePointer();
|
||||||
value = ~m_value.numerator();
|
value = ~m_value.numerator();
|
||||||
break;
|
break;
|
||||||
case Token::Add:
|
case Token::Add:
|
||||||
@ -640,7 +633,6 @@ TypePointer RationalNumberType::binaryOperatorResult(Token::Value _operator, Typ
|
|||||||
}
|
}
|
||||||
else if (_other->category() == Category::FixedPoint)
|
else if (_other->category() == Category::FixedPoint)
|
||||||
{
|
{
|
||||||
cout << "BINARY OPERATOR RESULTS" << endl;
|
|
||||||
shared_ptr<FixedPointType const> fixType = fixedPointType();
|
shared_ptr<FixedPointType const> fixType = fixedPointType();
|
||||||
if (!fixType)
|
if (!fixType)
|
||||||
return TypePointer();
|
return TypePointer();
|
||||||
@ -662,7 +654,6 @@ TypePointer RationalNumberType::binaryOperatorResult(Token::Value _operator, Typ
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "BINARY OPERATOR RESULTS PART 2" << endl;
|
|
||||||
shared_ptr<FixedPointType const> thisFixedPointType = fixedPointType();
|
shared_ptr<FixedPointType const> thisFixedPointType = fixedPointType();
|
||||||
shared_ptr<FixedPointType const> otherFixedPointType = other.fixedPointType();
|
shared_ptr<FixedPointType const> otherFixedPointType = other.fixedPointType();
|
||||||
if (!thisFixedPointType || !otherFixedPointType)
|
if (!thisFixedPointType || !otherFixedPointType)
|
||||||
@ -673,23 +664,23 @@ TypePointer RationalNumberType::binaryOperatorResult(Token::Value _operator, Typ
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
rational value;
|
rational value;
|
||||||
bool fixedPointType = (m_value.denominator() != 1 || other.m_value.denominator() != 1);
|
bool fractional = (m_value.denominator() != 1 || other.m_value.denominator() != 1);
|
||||||
switch (_operator)
|
switch (_operator)
|
||||||
{
|
{
|
||||||
//bit operations will only be enabled for integers and fixed types that resemble integers
|
//bit operations will only be enabled for integers and fixed types that resemble integers
|
||||||
case Token::BitOr:
|
case Token::BitOr:
|
||||||
if (fixedPointType)
|
if (fractional)
|
||||||
BOOST_THROW_EXCEPTION(Error(Error::Type::TypeError) << errinfo_comment("Cannot perform bit operations on non integer fixed type."));
|
return TypePointer();
|
||||||
value = m_value.numerator() | other.m_value.numerator();
|
value = m_value.numerator() | other.m_value.numerator();
|
||||||
break;
|
break;
|
||||||
case Token::BitXor:
|
case Token::BitXor:
|
||||||
if (fixedPointType)
|
if (fractional)
|
||||||
BOOST_THROW_EXCEPTION(Error(Error::Type::TypeError) << errinfo_comment("Cannot perform bit operations on non integer fixed type."));
|
return TypePointer();
|
||||||
value = m_value.numerator() ^ other.m_value.numerator();
|
value = m_value.numerator() ^ other.m_value.numerator();
|
||||||
break;
|
break;
|
||||||
case Token::BitAnd:
|
case Token::BitAnd:
|
||||||
if (fixedPointType)
|
if (fractional)
|
||||||
BOOST_THROW_EXCEPTION(Error(Error::Type::TypeError) << errinfo_comment("Cannot perform bit operations on non integer fixed type."));
|
return TypePointer();
|
||||||
value = m_value.numerator() & other.m_value.numerator();
|
value = m_value.numerator() & other.m_value.numerator();
|
||||||
break;
|
break;
|
||||||
case Token::Add:
|
case Token::Add:
|
||||||
@ -700,7 +691,7 @@ TypePointer RationalNumberType::binaryOperatorResult(Token::Value _operator, Typ
|
|||||||
break;
|
break;
|
||||||
case Token::Mul:
|
case Token::Mul:
|
||||||
value = m_value * other.m_value;
|
value = m_value * other.m_value;
|
||||||
break;
|
break;
|
||||||
case Token::Div:
|
case Token::Div:
|
||||||
if (other.m_value == 0)
|
if (other.m_value == 0)
|
||||||
return TypePointer();
|
return TypePointer();
|
||||||
@ -710,19 +701,22 @@ TypePointer RationalNumberType::binaryOperatorResult(Token::Value _operator, Typ
|
|||||||
case Token::Mod:
|
case Token::Mod:
|
||||||
if (other.m_value == 0)
|
if (other.m_value == 0)
|
||||||
return TypePointer();
|
return TypePointer();
|
||||||
else if (fixedPointType)
|
else if (fractional)
|
||||||
{
|
{
|
||||||
value = m_value;
|
value = m_value;
|
||||||
rational divisor = m_value / other.m_value;
|
if (value > other.m_value)
|
||||||
value -= divisor * m_value;
|
{
|
||||||
cout << "MODULO VALUE: " << value << endl;
|
do
|
||||||
|
{
|
||||||
|
value -= other.m_value;
|
||||||
|
} while (value > other.m_value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
value = m_value.numerator() % other.m_value.numerator();
|
value = m_value.numerator() % other.m_value.numerator();
|
||||||
break;
|
break;
|
||||||
case Token::Exp:
|
case Token::Exp:
|
||||||
{
|
{
|
||||||
cout << "Is this the source of the problem" << endl;
|
|
||||||
bigint newDenominator;
|
bigint newDenominator;
|
||||||
bigint newNumerator;
|
bigint newNumerator;
|
||||||
if (other.m_value.denominator() != 1)
|
if (other.m_value.denominator() != 1)
|
||||||
@ -769,14 +763,17 @@ string RationalNumberType::toString(bool) const
|
|||||||
u256 RationalNumberType::literalValue(Literal const*) const
|
u256 RationalNumberType::literalValue(Literal const*) const
|
||||||
{
|
{
|
||||||
u256 value;
|
u256 value;
|
||||||
|
unsigned uselessBits = 0;
|
||||||
|
bigint shiftedValue;
|
||||||
|
tie(shiftedValue, uselessBits) = findFractionNumberAndBits();
|
||||||
// we ignore the literal and hope that the type was correctly determined
|
// we ignore the literal and hope that the type was correctly determined
|
||||||
|
solAssert(shiftedValue <= u256(-1), "Integer constant too large.");
|
||||||
solAssert(m_value >= -(bigint(1) << 255), "Number constant too small.");
|
solAssert(shiftedValue >= -(bigint(1) << 255), "Number constant too small.");
|
||||||
|
|
||||||
if (m_value >= 0)
|
if (m_value >= 0)
|
||||||
value = u256(m_value.numerator());
|
value = u256(shiftedValue);
|
||||||
else
|
else
|
||||||
value = s2u(s256(m_value.numerator()));
|
value = s2u(s256(0 - shiftedValue));
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -794,6 +791,7 @@ TypePointer RationalNumberType::mobileType() const
|
|||||||
return fixType;
|
return fixType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: combine integerType() and fixedPointType() into one function
|
||||||
shared_ptr<IntegerType const> RationalNumberType::integerType() const
|
shared_ptr<IntegerType const> RationalNumberType::integerType() const
|
||||||
{
|
{
|
||||||
bigint value = wholeNumbers();
|
bigint value = wholeNumbers();
|
||||||
@ -813,52 +811,62 @@ shared_ptr<FixedPointType const> RationalNumberType::fixedPointType() const
|
|||||||
{
|
{
|
||||||
//do calculations up here
|
//do calculations up here
|
||||||
bigint integers = wholeNumbers();
|
bigint integers = wholeNumbers();
|
||||||
//bigint _remainder = abs(m_value.numerator() % m_value.denominator());
|
bigint shiftedValue;
|
||||||
|
unsigned integerBits = 0;
|
||||||
|
unsigned fractionalBits = 0;
|
||||||
bool fractionalSignBit = integers == 0; //sign the fractional side or the integer side
|
bool fractionalSignBit = integers == 0; //sign the fractional side or the integer side
|
||||||
bool negative = (m_value < 0);
|
bool negative = (m_value < 0);
|
||||||
//todo: change name
|
|
||||||
bigint fractionalBits = findFractionNumberAndBits();
|
|
||||||
cout << "Total int: " << fractionalBits.str() << endl;
|
|
||||||
if (negative && !fractionalSignBit) // convert to positive number of same bit requirements
|
if (negative && !fractionalSignBit) // convert to positive number of same bit requirements
|
||||||
{
|
{
|
||||||
integers = ((0 - integers) - 1) << 1;
|
integers = ((0 - integers) - 1) << 1;
|
||||||
fractionalBits = ((0 - fractionalBits) - 1) << 1;
|
integerBits = max(bytesRequired(integers), 1u) * 8;
|
||||||
|
tie(shiftedValue, fractionalBits) = findFractionNumberAndBits(integerBits);
|
||||||
}
|
}
|
||||||
else if (negative && fractionalSignBit)
|
else if (negative && fractionalSignBit)
|
||||||
fractionalBits = ((0 - fractionalBits) - 1) << 1;
|
tie(shiftedValue, fractionalBits) = findFractionNumberAndBits();
|
||||||
|
|
||||||
if (fractionalBits > u256(-1))
|
|
||||||
return shared_ptr<FixedPointType const>();
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "m_value: " << m_value << endl;
|
if (!fractionalSignBit)
|
||||||
cout << "Total int: " << fractionalBits.str() << endl;
|
integerBits = max(bytesRequired(integers), 1u) * 8;
|
||||||
unsigned fractionalBytesRequired = bytesRequired(fractionalBits) * 8;
|
tie(shiftedValue, fractionalBits) = findFractionNumberAndBits(integerBits);
|
||||||
unsigned integerBytesRequired = bytesRequired(integers) * 8;
|
if (shiftedValue == 0 && fractionalSignBit)
|
||||||
cout << "Fractional Bytes Required: " << fractionalBytesRequired << endl;
|
{
|
||||||
cout << "Integer Bytes Required: " << integerBytesRequired << endl << endl;
|
integerBits = 8;
|
||||||
|
fractionalBits = 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shiftedValue > u256(-1) || integers > u256(-1))
|
||||||
|
return shared_ptr<FixedPointType const>();
|
||||||
|
else
|
||||||
return make_shared<FixedPointType>(
|
return make_shared<FixedPointType>(
|
||||||
integerBytesRequired, fractionalBytesRequired,
|
integerBits, fractionalBits,
|
||||||
negative ? FixedPointType::Modifier::Signed : FixedPointType::Modifier::Unsigned
|
negative ? FixedPointType::Modifier::Signed : FixedPointType::Modifier::Unsigned
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo: change name of function
|
//todo: change name of function
|
||||||
tuple<bigint, unsigned> RationalNumberType::findFractionNumberAndBits(bool getWholeNumber) const
|
tuple<bigint, unsigned> RationalNumberType::findFractionNumberAndBits(unsigned const restrictedBits) const
|
||||||
{
|
{
|
||||||
rational value;
|
bool isNegative = m_value < 0;
|
||||||
if (getWholeNumber)
|
rational value = abs(m_value);
|
||||||
value = m_value;
|
unsigned fractionalBits = 0;
|
||||||
else
|
for (; fractionalBits <= 256 - restrictedBits; fractionalBits += 8, value *= 256)
|
||||||
value = m_value - wholeNumbers();
|
|
||||||
for (unsigned fractionalBits = 0; value < boost::multiprecision::pow(bigint(2), 256); fractionalBits += 8, value *= 10)
|
|
||||||
{
|
{
|
||||||
if (value.denominator() == 1)
|
if (value.denominator() == 1)
|
||||||
return make_tuple(value.numerator(), fractionalBits);
|
return make_tuple(value.numerator(), fractionalBits);
|
||||||
}
|
bigint predictionValue = 256 * (value.numerator() / value.denominator());
|
||||||
cout << "too big :(" << endl;
|
if (predictionValue > u256(-1))
|
||||||
return make_tuple(value.numerator()/value.denominator(), fractionalBits);
|
return make_tuple(value.numerator()/value.denominator(), fractionalBits);
|
||||||
|
predictionValue = ((0 - predictionValue) - 1) << 1;
|
||||||
|
if (predictionValue > u256(-1) && isNegative)
|
||||||
|
// essentially asking if its negative and if so will giving it a sign bit value put it over the limit
|
||||||
|
// if we also multiply it one more time by 256
|
||||||
|
return make_tuple(((0 - value.numerator() / value.denominator()) - 1) << 1, fractionalBits);
|
||||||
|
|
||||||
|
}
|
||||||
|
return make_tuple(value.numerator()/value.denominator(), 256 - restrictedBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -385,10 +385,11 @@ public:
|
|||||||
|
|
||||||
/// @returns the smallest integer type that can hold the value or an empty pointer if not possible.
|
/// @returns the smallest integer type that can hold the value or an empty pointer if not possible.
|
||||||
std::shared_ptr<IntegerType const> integerType() const;
|
std::shared_ptr<IntegerType const> integerType() const;
|
||||||
/// @returns the smallest fixed type that can hold the value or an empty pointer
|
/// @returns the smallest fixed type that can hold the value or incurs the least precision loss.
|
||||||
|
/// If the integer part does not fit, returns an empty pointer.
|
||||||
std::shared_ptr<FixedPointType const> fixedPointType() const;
|
std::shared_ptr<FixedPointType const> fixedPointType() const;
|
||||||
|
|
||||||
std::tuple<bigint, unsigned> findFractionNumberAndBits(bool getWholeNumber = false) const;
|
std::tuple<bigint, unsigned> findFractionNumberAndBits(unsigned const restrictedBits = 0) const;
|
||||||
bigint denominator() const { return m_value.denominator(); }
|
bigint denominator() const { return m_value.denominator(); }
|
||||||
bigint wholeNumbers() const { return m_value.numerator() / m_value.denominator(); }
|
bigint wholeNumbers() const { return m_value.numerator() / m_value.denominator(); }
|
||||||
|
|
||||||
|
@ -243,7 +243,6 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
|
|||||||
m_context << Instruction::MUL << Instruction::OR;
|
m_context << Instruction::MUL << Instruction::OR;
|
||||||
//else if (m_dataType->category() == Type::Category::Fixed)
|
//else if (m_dataType->category() == Type::Category::Fixed)
|
||||||
//trying to figure out what this does...going to require some more assistance
|
//trying to figure out what this does...going to require some more assistance
|
||||||
m_context << Instruction::MUL << eth::Instruction::OR;
|
|
||||||
// stack: value storage_ref updated_value
|
// stack: value storage_ref updated_value
|
||||||
m_context << Instruction::SWAP1 << Instruction::SSTORE;
|
m_context << Instruction::SWAP1 << Instruction::SSTORE;
|
||||||
if (_move)
|
if (_move)
|
||||||
|
@ -6634,7 +6634,7 @@ BOOST_AUTO_TEST_CASE(delete_on_array_of_structs)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(fixed_data_type)
|
/*BOOST_AUTO_TEST_CASE(fixed_data_type)
|
||||||
{
|
{
|
||||||
char const* sourceCode = R"(
|
char const* sourceCode = R"(
|
||||||
contract C {
|
contract C {
|
||||||
@ -6654,7 +6654,7 @@ BOOST_AUTO_TEST_CASE(fixed_data_type_expression)
|
|||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
compileAndRun(sourceCode, 0, "C");
|
compileAndRun(sourceCode, 0, "C");
|
||||||
}
|
}*/
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(internal_library_function)
|
BOOST_AUTO_TEST_CASE(internal_library_function)
|
||||||
{
|
{
|
||||||
|
@ -3278,16 +3278,16 @@ BOOST_AUTO_TEST_CASE(invalid_fixed_type_long)
|
|||||||
BOOST_CHECK(!success(text));
|
BOOST_CHECK(!success(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(valid_fixed_types)
|
BOOST_AUTO_TEST_CASE(valid_fixed_types_casting)
|
||||||
{
|
{
|
||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract test {
|
contract test {
|
||||||
function f(){
|
function f(){
|
||||||
fixed8x8 a = 87654321.12345678;
|
ufixed8x8 a = ufixed8x8(8765.1234);
|
||||||
fixed16x16 b = a**2;
|
ufixed16x16 b = a**2;
|
||||||
fixed24x24 c = b**3;
|
ufixed24x24 c = b**3;
|
||||||
fixed32x32 d = b**2;
|
ufixed32x32 d = b**2;
|
||||||
fixed40x40 e = a**5;
|
ufixed40x40 e = a**5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
@ -3310,7 +3310,7 @@ BOOST_AUTO_TEST_CASE(fixed_type_int_conversion)
|
|||||||
BOOST_CHECK(success(text));
|
BOOST_CHECK(success(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(fixed_type_const_int_conversion)
|
BOOST_AUTO_TEST_CASE(fixed_type_rational_conversion)
|
||||||
{
|
{
|
||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract test {
|
contract test {
|
||||||
@ -3328,8 +3328,8 @@ BOOST_AUTO_TEST_CASE(fixed_type_literal)
|
|||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract test {
|
contract test {
|
||||||
function f() {
|
function f() {
|
||||||
fixed a = 3.14;
|
fixed a = 4.5;
|
||||||
ufixed d = 2.555555;
|
ufixed d = 2.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
@ -3341,12 +3341,12 @@ BOOST_AUTO_TEST_CASE(fixed_type_literal_expression)
|
|||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract test {
|
contract test {
|
||||||
function f() {
|
function f() {
|
||||||
fixed a = 3.14 * 3;
|
ufixed8x248 a = 3.14 * 3;
|
||||||
ufixed b = 4 - 2.555555;
|
ufixed8x248 b = 4 - 2.555555;
|
||||||
fixed c = 1.0 / 3.0;
|
ufixed0x256 c = 1.0 / 3.0;
|
||||||
ufixed d = 599 + .5367;
|
ufixed16x240 d = 599 + .5367;
|
||||||
ufixed e = 35.245 % 12.9;
|
ufixed8x248 e = 35.245 % 12.9;
|
||||||
ufixed f = 1.2 % 2.00000;
|
ufixed8x248 f = 1.2 % 2;
|
||||||
fixed g = 2 ** -2;
|
fixed g = 2 ** -2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3354,6 +3354,19 @@ BOOST_AUTO_TEST_CASE(fixed_type_literal_expression)
|
|||||||
BOOST_CHECK(success(text));
|
BOOST_CHECK(success(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(rational_as_exponent_value)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
contract test {
|
||||||
|
function f() {
|
||||||
|
fixed g = 2 ** -2.2;
|
||||||
|
fixed b = 3 ** 2.56;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
BOOST_CHECK(!success(text));
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(fixed_type_invalid_size_conversion)
|
BOOST_AUTO_TEST_CASE(fixed_type_invalid_size_conversion)
|
||||||
{
|
{
|
||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
@ -3408,7 +3421,7 @@ BOOST_AUTO_TEST_CASE(mapping_with_fixed_literal)
|
|||||||
{
|
{
|
||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract test {
|
contract test {
|
||||||
mapping(fixed => string) fixedString;
|
mapping(ufixed8x248 => string) fixedString;
|
||||||
function f() {
|
function f() {
|
||||||
fixedString[3.14] = "Pi";
|
fixedString[3.14] = "Pi";
|
||||||
}
|
}
|
||||||
@ -3434,7 +3447,7 @@ BOOST_AUTO_TEST_CASE(inline_array_fixed_rationals)
|
|||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract test {
|
contract test {
|
||||||
function f() {
|
function f() {
|
||||||
ufixed8x16[4] memory a = [3.5, 4.1234, 2.5, 4.0];
|
ufixed8x248[4] memory a = [3.5, 4.1234, 2.5, 4.0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
@ -3445,8 +3458,8 @@ BOOST_AUTO_TEST_CASE(zero_and_eight_variants_fixed)
|
|||||||
{
|
{
|
||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract A {
|
contract A {
|
||||||
fixed8x0 someInt = 4;
|
ufixed8x0 someInt = 4;
|
||||||
fixed0x8 half = 0.5;
|
ufixed0x8 half = 0.5;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
BOOST_CHECK(success(text));
|
BOOST_CHECK(success(text));
|
||||||
@ -3457,9 +3470,9 @@ 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() {
|
||||||
ufixed0x8 a = 0.12345678;
|
ufixed0x256 a = 0.12345678;
|
||||||
ufixed8x0 b = 12345678.0;
|
ufixed24x0 b = 12345678.0;
|
||||||
ufixed0x8 c = 0.00000009;
|
ufixed0x256 c = 0.00000009;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
@ -3510,13 +3523,38 @@ BOOST_AUTO_TEST_CASE(fixed_point_casting_exponents)
|
|||||||
BOOST_CHECK(success(text));
|
BOOST_CHECK(success(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(rational_to_bytes_implicit_conversion)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
contract test {
|
||||||
|
function f() {
|
||||||
|
bytes32 c = 3.183;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
BOOST_CHECK(success(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(fixed_to_bytes_implicit_conversion)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
contract test {
|
||||||
|
function f() {
|
||||||
|
fixed a = 3.183;
|
||||||
|
bytes32 c = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
BOOST_CHECK(!success(text));
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(rational_unary_operation)
|
BOOST_AUTO_TEST_CASE(rational_unary_operation)
|
||||||
{
|
{
|
||||||
char const* text = R"(
|
char const* text = R"(
|
||||||
contract test {
|
contract test {
|
||||||
function f() {
|
function f() {
|
||||||
fixed a = +3.5134;
|
ufixed8x248 a = +3.5134;
|
||||||
fixed b = -2.5145;
|
fixed8x248 b = -3.5134;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
Loading…
Reference in New Issue
Block a user