Каков самый дешевый способ roundup() или ceil() до числа, кратного 1000?

Каков самый дешевый способ roundup() или ceil() до числа, кратного 1000?

Например, если в функции ceil реализован самый дешевый способ округления:

function ceil(uint a, uint m) returns (uint) {
    //some cheap roundup to muliple function
}

то ожидается, что:

  • потолок(123456,1000) == 124000
  • потолок(1,1000) == 1000
  • потолок (0,1000) == 0
  • потолок(123000,1000) == 123000

Ответы (2)

Вот одно из решений:

contract Ceil {
    function ceil(uint a, uint m) constant returns (uint ) {
        return ((a + m - 1) / m) * m;
    }

    // To measure gas
    function ceil1(uint a, uint m) returns (uint ) {
        return ((a + m - 1) / m) * m;
    }
}

И тестирование на правильные результаты:

> ceil.ceil(123456, 1000)
124000
> ceil.ceil(1,1000)
1000
> ceil.ceil(0,1000)
0
> ceil.ceil(123000,1000)
123000

Для измерения газа я создал ceil1(...)и отправил транзакцию:

> ceil.ceil1(123456, 1000, eth.accounts[0], {
   from:web3.eth.accounts[0], 
   data: ceilCompiled.Ceil.code,
   gas: 1000000
});
"0xeac6bb84ba5a1703ee3a762cb392f1793adf550906b6112e441928c0ea288f53"
...
> debug.traceTransaction("0xeac6bb84ba5a1703ee3a762cb392f1793adf550906b6112e441928c0ea288f53")
{
  gas: 21990,
  returnValue: "000000000000000000000000000000000000000000000000000000000001e460",
  structLogs: [{

Стоимость газа по этому расчету составляет 21 990. Эта цифра будет включать 21 000 газа по умолчанию для отправки обычной транзакции, что дает дополнительную стоимость газа 990.

При подключении кода к онлайн-компилятору Solidity по адресу https://chriseth.github.io/browser-solidity/#version=soljson-latest.js оценивается следующая стоимость газа:

Creation: 69 + 43000
External:
  ceil(uint256,uint256): 275
  ceil1(uint256,uint256): 253
Internal:

Таким образом, оценка стоимости газа ceil1(...)составляет от 253 до 990.

Я не знаю, самое ли это дешевое, но одно из решений, которое мне удалось придумать, это:

function ceil(uint a, uint m) returns (uint r) {
    return (a + m - 1) / m * m;
}