27

I'm building a new smart contract but really can't figure out how to perform integer division. I know that fixed point numbers haven't been implemented yet but it should be possible to perform 100/3 = 33, at least.

I hope someone can help me. I have seen multiple examples where they talk about rounded integer division but can't seem to be able to perform it.

Cheers, Hugo

3
  • Just to display the error message : ballot.sol:3:19: Error: Type rational_const 5/4 is not implicitly convertible to expected type uint256. Try converting to type ufixed8x8 or use an explicit conversion. uint result = 5/4 I understand that casting is not implicitly possible but explicit isn't either and I don't see anything I can do to achieve integer division Commented Apr 10, 2017 at 18:04
  • Could you post your code, and the solidity version you're using? Commented Apr 10, 2017 at 18:13

4 Answers 4

28

Problem is 4 & 5 fit in less that 256 bits (each). You end up with tiny uints in the constant expression, and then those aren't easily converted to the uint256, so ... cast the type explicitly.

uint x = uint(4)/uint(5);

Takeaway is caution with constants because they may be cast in unexpected types.

A sketchy idea:

contract Divide {
    
    function getDivided(uint numerator, uint denominator) public constant returns(uint quotient, uint remainder) {
        quotient  = numerator / denominator;
        remainder = numerator - denominator * quotient;
    }
}

Also check out "SafeMath" with "safeDiv()" at Zeppelin: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol

Also, since 4/5 obviously works out to 0 remainder 4, possibly you're really aiming for something more like 80%?

You can bump up the accuracy by working with "decimal" as is common in financial markets. You pass pairs around, the digits and the decimal offset.

So, 1.234 would be written as [1234, 3] with the 3 indicating that there is a decimal in the third spot.

In this case, you would calculate 80, with 2 decimal places (meaning .80).

4 * 10 ** 2 = 400, 400/5 = 80, we raised 4 by 10 ^ 2, so return ... 80,2 and optionally, a remainder.

Hope it helps.

4
  • Wow Rob, thank you so much for your help, we felt completely lost on this ! Commented Apr 11, 2017 at 6:37
  • 1
  • In my tests, it was enough to only use uint x = uint(4)/5;. Seems as if the denominator does not need a cast if the nominator is of the same type and gets a cast. Commented Jan 6, 2022 at 18:25
  • In practice, it's usually enough to know that truncation, not rounding takes place and dust exists. 4/5 = 0. ` function foo() public pure returns(uint x) { x = uint(4)/5; } ` Commented Jan 6, 2022 at 20:37
5

as an addition to @rob's answer you can use :

 function calcul(uint a, uint b, uint precision) view returns ( uint) {

     return a*(10**precision)/b;
 }

If we divide using the function above 7/3 with a precision of 5 it will output 233333 which means 7/3=2.33333. The conversion to float can be done in the front-end.

1

Literal expressions have arbitrary precision until converted (eg. casted) to a non-literal type.

In this example, the literal expression 5/4 is an internal rational constant type with unlimited precision, and cannot be implicitly downcasted to a uint256. This is apparently a restriction on rationals imposed by the compiler.

Note that for whole-number literal expressions, the resulting type is the smallest one that will contain the value of the expression.

See also:

http://solidity.readthedocs.io/en/develop/types.html#rational-literals https://ethereumbuilders.gitbooks.io/guide/content/en/solidity_features.html

1

You may use fixed point math library such as ABDK Math 64.64. It has method divi that divides one integer by another and returns the result as binary fixed point number with 64 binary digits after dot.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.