26

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

Paul Razvan Berg
  • 17,902
  • 6
  • 73
  • 143
Hugo Moreau
  • 263
  • 1
  • 3
  • 4

4 Answers4

27

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.

chenyu
  • 3
  • 2
Rob Hitchens
  • 55,151
  • 11
  • 89
  • 145
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.

Badr Bellaj
  • 18,780
  • 4
  • 58
  • 75
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

jordanpg
  • 195
  • 6
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.

Mikhail Vladimirov
  • 7,313
  • 1
  • 23
  • 38