如何计算blockChain实体的PMT函数(财务函数)

问题描述 投票:0回答:2

如何将此代码(javascript代码)转换为可靠性代码,它将工作?

function pmt(rate_per_period, number_of_payments, present_value, future_value){
if(rate_per_period != 0.0){
    // Interest rate exists
    var q = Math.pow(1 + rate_per_period, number_of_payments);
    return (rate_per_period * (future_value + (q * present_value))) / ((q-1) * (1 + rate_per_period ));

} else if(number_of_payments != 0.0){
    // No interest rate, but number of payments exists
    return -(future_value + present_value) / number_of_payments;
}

return 0;}

已经完成了这个功能:

function PMT(uint _rate,uint256 _term,uint _pv) public view returns (uint)
{
     uint q = ((1 + _rate) ** _term);
    return (_rate *  (((1 + _rate) ** _term) * _pv)) / ((((1 + _rate) ** _term)-1) * (1+_rate));
}

并且,我如何在实体中表示十进制值? Solidity尚未完全支持定点数。它们可以声明,但不能分配给或来自。

例如函数参数:

pmt(0.0025,12,700000);

*************编辑

乘法函数不会工作

PMT的论点:

  1. totalFunding(700000)
  2. totalMonths(12)
  3. totalYears(1)
  4. annualYieldInterest(3% - 0.03)

如果我将通过10 ** 2 = 100给它们供电,参数将为:

  1. 总福利(70,000,000)
  2. totalMonths(1200)
  3. totalYears(100)
  4. annualYieldInterest(3% - 0.03 - 3)

在我开始计算PMT函数之前,我必须计算他得到的参数:

  1. 总福利:70,000,000
  2. 速率:3/1200 - 0.0025(通过上述参数)
  3. totalMonths:12

所以我仍然得到浮动价值。

blockchain solidity financial
2个回答
0
投票

最好的办法是将所有值乘以10的幂,这样就不再有浮点数了。然后执行计算,并将结果值除以合约之外的10**decimals

这与各种令牌用于跟踪余额的方法相同。


0
投票

你可以使用ABDK Math 64.64库。它具有您需要的所有功能(addsubmuldivnegpow)并使用定点数运算。注意,这是使用二进制而不是十进制的固定点,在点后有64位二进制数字。因此,为了将十进制数转换为二进制固定点,您基本上需要将其乘以2 ^ 64。要从固定点转换为十进制,只需除以2 ^ 64。

使用此库,您的Javascript函数可能会像这样移植到Solidity:

function pmt (
  int128 rate_per_period, int128 number_of_payments,
  int128 present_value, int128 future_value) public pure returns (int128) {
  if (rate_per_period != 0) {
    // Interest rate exists
    int128 q =
      ABDKMath64x64.pow (
        ABDKMath64x64.add (
          0x10000000000000000,
          rate_per_period),
        ABDKMath64x64.toUInt (
          number_of_payments));
    return
      ABDKMath64x64.div (
        ABDKMath64x64.mul (
          rate_per_period,
          ABDKMath64x64.add (
            future_value,
            ABDKMath64x64.mul (
              q,
              present_value))),
        ABDKMath64x64.mul (
          ABDKMath64x64.sub (
            q,
            0x10000000000000000),
          ABDKMath64x64.add (
            0x10000000000000000,
            rate_per_period)));
  } else if (number_of_payments != 0) {
    // No interest rate, but number of payments exists
    return
      ABDKMath64x64.div (
        ABDKMath64x64.neg (
          ABDKMath64x64.add (
            future_value,
            present_value)),
        number_of_payments);
  } else return 0;
}

请注意,1成为0x10000000000000000,即2 ^ 64。在将所有参数传递给此函数之前,您需要将所有参数乘以2 ^ 64,并且在使用之前需要将结果除以2 ^ 64。

我刚刚使用以下参数在Remix中尝试了这个Solidity函数:

rate_per_period = 0.03    // = 0x7AE147AE147AE14 / 2^64
number_of_payments = 10.0 // = 0xA0000000000000000 / 2^64
present_value = 1.0       // = 0x10000000000000000 / 2^64
future_value = 2.0        // = 0x20000000000000000 / 2^64

它返回给我0.2832= 0x487F82986F5A14DC / 2^64),这与你的Javascript函数返回这些参数相同。

© www.soinside.com 2019 - 2024. All rights reserved.