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.
The functions seem weird...
If this is a function that takes money from a user (they are calling payable function and sending your contract money), then why are you subtracting money from their internal balance?
They are depositing money, their balance should increment.
As for accepting a fixed amount of eth, what do you mean? You want the function to be executed only if the amount sent to it is = to certain value? If so:
// This function will fail if the buyer doesn't send the exact amount of money.
function buySomething() payable{
uint exactAmount = 3000;
require (msg.value == exactAmount);
boughtSomething = true;
}
If you want to accept any amount and return the difference:
function buySomethingAndReturnChange() payable{
uint minAmount = 3000;
require (msg.value >= minAmount);
uint moneyToReturn = msg.value - minAmount;
boughtSomething = true;
if(moneyToReturn > 0)
msg.sender.transfer(moneyToReturn);
}
Best Answer
I managed to implement both
floor
andceil
as follows. TheABDKMath64x64.toInt
function essentially floors the signed fixed point number to a signed integer, hence the following would hold true:toInt(-18444899399302180000) == -1
i.e. floor(-0.9999) == -1toInt(0) == 0
i.e. floor(0) == 0toInt(18444899399302180000) == 0
i.e. floor(0.9999) == 0toInt(18446744073709551616) == 1
i.e. floor(1) == 1toInt(-18446744073709551616) == -1
i.e. floor(-1) == -1so all that is required is to then just cast the resulting integer result back to a signed fixed point number.
For
ceil
I first check if the signed fixed point number is a whole number integer by %(mod) by 1(unity), if it is then I simply return the number since the ceil of a whole number is that number. Else I take the fixed point number into the real number range above it's current real number range and then floor it, so for example if the number is0.9999
I take it into the range of it's ceil i.e. [1, 2) by adding unity which makes it 1.9999, then flooring it gives us the ceil i.e. 1 in this case. hence the following holds true:ceil(-18444899399302180000) == 0
i.e. ceil(-0.9999) == 0ceil(0) == 0
i.e. ceil(0) == 0ceil(18444899399302180000) == 0
i.e. ceil(0.9999) == 1ceil(18446744073709551616) == 1
i.e. ceil(1) == 1ceil(-18446744073709551616) == -1
i.e. ceil(-1) == -1