Division/percentages is a required part of many applications but is difficult to implement since fixed
and ufixed
are not supported yet in Solidity. I've come up with this workaround:
pragma solidity ^0.4.9;
contract Math {
function Math() public {}
function percent(uint a, uint b) public constant returns(uint, uint) {
uint c = a*b;
uint integer = c/100;
uint fractional = c%100;
return (integer, fractional);
}
}
If I want to get 12% of 27 and call percent(27, 12)
, I correctly get back 3
and 24
representing 3.24
. The limitation to this of course is that percent(12.5, 100)
isn't possible.
However if I call percent(17, 359)
, I get back 61
and 3
. The real result is 61.03
, however, because fractional
is a uint
, the 0 in front of the 3 is dropped. Is there a way to find out if a fractional has a leading zero?
Best Answer
In my opinion this is probably an inappropriate use of on-chain logic, not only because of the attendant awkwardness of the code, but also because of the gas cost involved in doing something the caller can easily figure out for themselves.
Having said that, one could deal with decimal places using something like this: Can't do any integer division
This interpretation returns an integer percentage properly rounded up. For example, 23.5% returns 24. You could increase the decimals of precision by tinkering with the way it plays with the integer conversions.
Hope it helps.
UPDATE
To do the reverse, as follows. Also, increase the order of magnitude to return a result with higher precision.
Here, 12 over 27 (12,27) returns 324 which the client can interpret as 32.4%.
The main takeaway is to work with integers. The trickery with
+5
and/10
is to ensure correct rounding up.