Comments (4)
@Lohann in that case, and seeing as division by zero stopped yielding a zero since 0.4.21, your only option is to implement the desired behaviour inside an assembly block.
from solidity.
as per my observation , the unchecked blocks underflow checks and also the disable overflow . if we want to solve this bug you can just simply add the "check" before doing division calculation.
from solidity.
Hi @Lohann. This isn't a bug, and is in fact by design, and has also been in Solidity since way before the unchecked arithmetic was implemented and became default in 0.8.0.
Division (and modulo) by zero wasn't actually reverting pre 0.4.21, and was reported in #2694. It was then implemented in #3523, and finally released as part of the 0.4.21 version.
It's also stated in the docs.
The reason for this is that division by zero abstract, and most languages either have it as undefined behaviour, or they'll throw an exception, or they may have an infinite value defined (e.g. Inf
) which can be returned in such cases. In Solidity, the only thing that really makes sense is to revert, which is why it's the way it is, and why it won't change in the future.
If you're really adamant about not having this check (which in essence is just an ISZERO
opcode with a conditional JUMPI
), then you can implement the arithmetic in an inline assembly block. I would however advise against it, since I doubt that the gas gains would be significant enough to justify the 'risk'.
An important thing to note that may or may not be helpful is that the division by zero on the EVM level behaves by returning zero, i.e. x / 0 = 0
, which from an arithmetic perspective, is not ideal as it can produce ambiguity.
from solidity.
@nikola-matic I see, yeah I rely on the zero result in my algorithm, this is the saturating multiplication that consumes 46 gas
:
function saturatingMul(uint256 a, uint256 b) external pure returns (uint256) {
unchecked {
uint256 c = a * b;
bool success = (c / a) == b || a == 0; // Doesn't works because reverts here when a == 0
uint256 limit = SafeCast.toUint(success) - 1;
return c | limit;
}
}
Assembly version:
PUSH1 0xBB // b
PUSH1 0xAA // a b
// -- c = a * b
DUP2 // b a b
DUP2 // a b a b
MUL // c a b
// -- success = (c / a) == b || a == 0
SWAP2 // b a c
DUP2 // a b a c
DUP4 // c a b a c
DIV // (c / a) b a c
EQ // ((c / a) == b) a c
PUSH1 1 // 1 ((c / a) == b) a c
SWAP2 // a ((c / a) == b) 1 c
ISZERO // (a == 0) ((c / a) == b) 1 c
OR // success 1 c
// -- limit = successs - 1
SUB // limit c
// -- result = success ? c : limit
OR // result
from solidity.
Related Issues (20)
- Segmentation fault in solc in function solidity::frontend::experimental::Analysis::annotationContainer, file libsolidity/experimental/analysis/Analysis.cpp HOT 6
- Deduplicate bytecode dependencies used by both creation and deployed object HOT 2
- Reuse optimized IR/bytecode for bytecode dependencies
- SMTChecker: Underflow and overflow targets not checked or reported on the same expression for BMC engine HOT 1
- Redundant `ISZERO` and `PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND` in covertType
- [Yul EVM code transform] Stack too deep in standalone Yul test case
- ICE in `Z3Interface::fromZ3Expr()` when running tests on Arch Linux HOT 8
- Seems like an incorrect type inference... HOT 3
- Update Z3 to 4.13.0 or later HOT 1
- Consider changing linker on Linux from `ld.gold` to `ld`
- Copyright year is 2016-2023 instead of 2016-2024 HOT 1
- Where can I find Test Sepolia so I can deploy a contract on a testnet? HOT 1
- Segfault in AsmParser for debug-compiled solc
- Copyright years are 2016-2023, should to be 2016-2024 HOT 1
- Support for CodeSection type for linking externally written/compiled bytecode with EOF supported Solidity contracts. HOT 1
- require() to accept custom errors instead of a message HOT 2
- solc --gas outputs nothing
- A possible lack of warning for no-effect statement "x + 2";
- Segmentation Fault due to a possible syntax error HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from solidity.