8

I'd like to multiply Ether by a decimal (a proportion, e.g. 0.05). I've got:

ufixed proportion; // What type should proportion be?

function functionName() {
  var Ether = msg.value; // (in units of wei)
  var proportionOfEther = Ether * proportion
  ...

My Solidity linter is saying that * is not compatible with uint256 (the Ether) and ufixed128x128 (the proportion).

Will White
  • 115
  • 1
  • 6
  • msg.value is in Wei not Ether. It should be quite a big number, because Wei are very small. Life is easier if you just avoid decimals, eg store your proportion as percent, divide by 100 and multiply by it. – Edmund Edgar Jan 30 '17 at 23:39
  • See http://ethereum.stackexchange.com/questions/11733/building-a-floating-rate-on-the-tokens for an example – BokkyPooBah Jan 31 '17 at 00:09

4 Answers4

9

Instead of multiplying by a decimal, multiply and divide by integers.

i.e. (Ether * 5)/100

Tjaden Hess
  • 37,046
  • 10
  • 91
  • 118
  • 2
    This is exactly what you should do, but be certain to use the parens to do it in the order shown. If you divide first, I think you would get a different result due to truncation. Also, if I were you, I would be careful to think in terms of wei, not ether. The assignment var Ether = msg.value is already a bit off (at least the name of the variable is) because msg.value is in wei. You comments says that, but the variable name disagrees. A minor point, I know, but when dealing with this stuff, you have to be super careful in my experience. – Thomas Jay Rush Jan 31 '17 at 00:02
  • 1
    ^This is important. Whenever possible, avoid using Ether as a unit. It is far easier to reason about an integer quantity of Wei than a fractional quantity of ether. – Tjaden Hess Jan 31 '17 at 00:05
  • @ThomasJayRush TjadenHess Thank you, I have changed the variable names to wei. I was using Ether to refer to the currency, not the denomination, but that isn't important. – Will White Jan 31 '17 at 11:50
  • also you should note that the namesether, wei, finney, etc. are reserved in Solidity. (ether == 10**18, finney == 10**15, etc.) – Tjaden Hess Jan 31 '17 at 16:12
  • If I have 7 Ether, then the result will be 0.35. At any rate, it will get chopped off as a zero. – Jossie Calderon Jun 15 '17 at 08:01
0

You can use DS-Math (I answered that here in more detail)

CodingYourLife
  • 729
  • 1
  • 6
  • 18
0

fixed point math does not work in solidity yet.

See https://solidity.readthedocs.io/en/v0.4.24/types.html

That is why you need to use the methods listed above.

Dave Appleton
  • 280
  • 2
  • 5
0

You may use mulu function from ABDK Math 64.64 library. It multiplies uint value by 64.64-bit fixed point number.

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