10

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

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

Cheers,

  • 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 – Hugo Moreau Apr 10 '17 at 18:04
  • Could you post your code, and the solidity version you're using? – Dennis Peterson Apr 10 '17 at 18:13
16

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/zeppelin-solidity/blob/master/contracts/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.

  • Wow Rob, thank you so much for your help, we felt completely lost on this ! – Hugo Moreau Apr 11 '17 at 6:37
2

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, privacy policy and cookie policy

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