diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 15fdd1ff6..546468f69 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -915,11 +915,13 @@ void CompilerUtils::convertType( else solAssert(false, ""); + bigint factor = pow(bigint(10), static_cast(abs(digitDifference))); + solAssert(0 <= factor && factor <= std::numeric_limits::max(), ""); if (digitDifference > 0) - m_context << pow(u256(10), static_cast(digitDifference)) << Instruction::MUL; + m_context << u256(factor) << Instruction::MUL; else if (digitDifference < 0) m_context << - pow(u256(10), static_cast(-digitDifference)) << + u256(factor) << Instruction::SWAP1 << (isSigned ? Instruction::SDIV : Instruction::DIV); diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index c85d4a495..4b36553a9 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -499,10 +499,12 @@ string YulUtilFunctions::fixedPointShiftFunction(int _digits, bool _signed) return m_functionCollector.createFunction(functionName, [&](vector& _args, vector& _ret) { _args = {"value"}; _ret = {"result"}; + bigint factor = bigint("1" + string(static_cast(abs(_digits)), '0')); + solAssert(factor < (bigint(1) << 256), ""); return Whiskers("result := (value, )") ("op", _digits >= 0 ? "mul" : _signed ? "sdiv" : "div") - ("factor", ("1" + string(static_cast(abs(_digits)), '0'))) + ("factor", factor.str()) .render(); }); } diff --git a/test/libsolidity/semanticTests/fixedPoint/conversion_large.sol b/test/libsolidity/semanticTests/fixedPoint/conversion_large.sol new file mode 100644 index 000000000..de4829caf --- /dev/null +++ b/test/libsolidity/semanticTests/fixedPoint/conversion_large.sol @@ -0,0 +1,10 @@ +contract C { + function test() public pure returns (uint a) { + ufixed256x77 x = 1.0000001234; + return uint(x); + } +} +// ==== +// compileViaYul: also +// ---- +// test() -> 0