I am creating a contract that issues tokens. I would like an account that holds tokens to be able to check what percentage they own out of all the tokens issued. I know that Ethereum has not implemented floating point numbers yet. What should I do?
2 Answers
It's probably best (lowest gas cost and trivial to implement) to perform that calculation on the client rather than in Solidity.
If you find you need it in Solidity, then it's just a matter of working with integers by shifting the decimal point. Similar to: https://en.wikipedia.org/wiki/Parts-per_notation
For example, this function let's you decide the degree of precision and uses one extra degree of precision to correctly round up:
pragma solidity ^0.4.6;
contract Divide {
function percent(uint numerator, uint denominator, uint precision) public
constant returns(uint quotient) {
// caution, check safe-to-multiply here
uint _numerator = numerator * 10 ** (precision+1);
// with rounding of last digit
uint _quotient = ((_numerator / denominator) + 5) / 10;
return ( _quotient);
}
}
If you feed it 101,450, 3 you get 224, i.e. 22.4%.
Hope it helps.

- 1,049
- 10
- 14
-
This would be needed for a calculation of how much the contract is able to pay out for the given token holder. For example if a token holder owns 20 tokens and there are 100 total tokens. The contract needs to be able to decide that 20 tokens is worth 20% of the total ether in the contract. The total ether may be 5 eth for example. Could I divide Wei? How would this work? – GK1 Mar 11 '17 at 20:58
-
Fair enough, and No. The Wei is the smallest unit so you have to decide what to do with remainders. If you're going for full precision, then track fractional Wei using higher precision user balances as state variables ... occasional settlement when cumulative balance is large enough. Remember, it will cost gas to actually move a single unit of Wei so think about the efficiency of moving small amounts around. – Rob Hitchens Mar 11 '17 at 21:21
-
Ok, so how would I multiply that percentage? I would first need to turn it into a decimal (not sure how to do that), than I would need to multiply it by the [this].balance? By the way thanks for the help. – GK1 Mar 11 '17 at 21:40
-
1Well, if you pass 20,100,3 then you get 200 - let's call it "portion"), meaning 200 parts per thousand, or 20.0%. So, you can have as much precision as you need. Then, you could say amountToDivide * portion / 1000. 1,000 is 3(the original precision)**10. I corrected an oversight in the function so it correctly rounds up. BTW, "convert to decimal" is a shorthand I've heard in financial circles ... means multiply by 100. Nothing special. Also, comment about "safe-to" is in case you are dealing with large numbers that could overflow and do nasty things. – Rob Hitchens Mar 11 '17 at 22:01
-
So in what conditions would it not be safe to multiply? – GK1 Mar 11 '17 at 22:17
-
2Overflow. If the number is too large for uint256 it won't throw ... it'll just toss the high order bits and return a small number. Why you see example like if(a+b – Rob Hitchens Mar 11 '17 at 22:35
-
Sorry for the silly question, but what is "5" from Rob's quotient equation? – Paul Razvan Berg Jul 04 '19 at 18:04
-
It handles rounding up because otherwise, Solidity truncates. – Rob Hitchens Jul 04 '19 at 18:22
You could use binary point
or fixed number representation
. Introduction to Fixed Point Number Representation For example
11010.1 in base2 = 1 * 24 + 1 * 23 + 0 * 22 + 1 * 21 + 0* 20 + 1 * 2-1 = 26.5
Percentage is calculated by
// x is the percentage
a/b = x/100 => x= (100*a)/b
to calculate the division of big numbers, you can use FixidityLib.sol library.
function divide(Fixidity storage fixidity, int256 a, int256 b) public view returns (int256) {
if(b == fixidity.fixed_1) return a;
assert(b != 0);
return multiply(fixidity, a, reciprocal(fixidity, b));
}
There are too many mathematical libraries or contracts and each implements divide operation differently:
DSMath Contract

- 35,338
- 10
- 157
- 202