如何将此代码(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的论点:
如果我将通过10 ** 2 = 100给它们供电,参数将为:
在我开始计算PMT函数之前,我必须计算他得到的参数:
所以我仍然得到浮动价值。
最好的办法是将所有值乘以10的幂,这样就不再有浮点数了。然后执行计算,并将结果值除以合约之外的10**decimals
。
这与各种令牌用于跟踪余额的方法相同。
你可以使用ABDK Math 64.64库。它具有您需要的所有功能(add
,sub
,mul
,div
,neg
,pow
)并使用定点数运算。注意,这是使用二进制而不是十进制的固定点,在点后有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函数返回这些参数相同。