如何转换此代码(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函数之前,我必须计算他得到的参数:
所以我仍然得到浮点值。
答案 0 :(得分:0)
您最好的选择是将所有值乘以10的幂,这样您就不再具有浮点数了。然后执行计算,并将结果值除以合同外的10**decimals
。
这与各种令牌用于跟踪余额的方法相同。
答案 1 :(得分:0)
您可以使用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函数针对这些参数返回的结果相同。