处理智能合约中的小数

密码学 中,我们经常使用无符号整数,而不会在浮点值中做太多事情。但是,很明显,我们的许多计算都需要浮点值,例如计算金融合约中的复利或计算圆的面积。因此,如果我们需要在智能合约中实现小数运算,我们需要添加处理小数值但使用整数运算的代码。

在密码学中,我们经常使用无符号整数,而不会在浮点值中做太多事情。但是,很明显,我们的许多计算都需要浮点值,例如计算金融合约中的复利或计算圆的面积。因此,如果我们需要在智能合约中实现小数运算,我们需要添加处理小数值但使用整数运算的代码。

小数运算的基础

我们来看看如何用小数来进行数学运算。例如,一些简单的计算如下:

6.1 + 5.2 = 11.3

6.1 * 5.2 = 31.72

6.1 - 5.2 = 0.9

6.1 / 5.2 = 1.173

1/6.1 = 0.1639

支持小数的一种方法是移动小数点,使其看起来像一个整数。例如,6.546可以是6546,3.134可以是3134。只要我们记住小数点移动了多少位,就可以反向运算。加起来很简单:

6546 + 3134 = 9679

小数点移三位,得到9.679。当我们相乘时,我们得到:

6546 *3134 = 20512030

这一次,因为我们要相乘,所以我们需要将小数点的位数移动两倍于所移动的位数(正如你在学校里记得的那样),所以我们得到:

20.512030

用除法,我们取除数的倒数,然后乘以它。

定点小数

有一系列的库可以用于我们的智能合约,比如ABDK和fixidity。在这种情况下,我们得到:它需将符号移动24 位。对于 1 的值,我们得到:

1000000000000000000000000

小数点后24位,然后是整个部分。所以,这是我们的一些solidity代码:

pragma solidity ^0.5.0;

import "https://github.com/CementDAO/Fixidity/blob/master/contracts/FixidityLib.sol";

contract Maths {

    function abs(int256 x) public pure returns (int256) {
        return FixidityLib.abs(x);
    }

    function multiply(int256 a, int256 b) public pure returns (int256) {
        return FixidityLib.multiply(a, b);
    }

    function reciprocal(int256 a) public pure returns (int256) {
        return FixidityLib.reciprocal(a);
    }

    function divide(int256 a, int256 b) public pure returns (int256) {
        return FixidityLib.divide(a, b);
    }

    function add(int256 a, int256 b) public pure returns (int256) {
        return FixidityLib.add(a, b);
    }

    function subtract(int256 a, int256 b) public pure returns (int256) {
        return FixidityLib.subtract(a, b);
    }

}

我们首先在Remix中输入代码:

1.jpg

接下来,我们可以运行本地区块链(使用ganache),然后部署我们的智能合约:

2.jpg

我们可以看到,部署智能合约的地址已经收取了一些以太来进行挖矿,接下来,我们可以测试它。

3.jpg

答案是:1130000000000000000000。如果将小数点数到 24 位,我们得到:11.300000000000000000000000,这是 6.1 + 5.2 的正确答案。

再减去(a-b)和倒数(1/x)。

4.jpg

对于减法,我们得到:900000000000000000000000,即 0.900000000000000000000000(当我们移动小数点后 24 位时)。同样,这对于 6.1-5.2 是正确的。

对于倒数,我们实现了1除以6.1。我们可以看到答案是163934426229508196721311,当我们移动24位小数点后得到0.163934426229508196721311。

现在我们把6.1和5.2相乘:

5.jpg

相乘得到:3172000000000000000000,小数点后移24位得到31.72000000000000000000。最后,我们将进行除法:

6.jpg

对于除法,我们得到:1173076923076853846153842,当我们移动小数点后24位时,是:1.173076923076853846153842。这也是6.1/5.2的正确答案。该库还会给出数字的小数部分,例如6.1:

7.jpg

小数形式是0.1。

Source:https://medium.com/asecuritysite-when-bob-met-alice/dealing-with-decimals-in-smart-contracts-fd27eea9209a

关于

ChinaDeFi - ChinaDeFi.com 是一个研究驱动的DeFi创新组织,同时我们也是区块链开发团队。每天从全球超过500个优质信息源的近900篇内容中,寻找思考更具深度、梳理更为系统的内容,以最快的速度同步到中国市场提供决策辅助材料。

本文首发于:https://mp.weixin.qq.com/s/lhlzNhbnCskjF0Db9p5dCA

点赞 0
收藏 1
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
ChinaDeFi 去中心化金融社区
ChinaDeFi 去中心化金融社区
ChinaDeFi.com 是一个研究驱动的DeFi创新组织,同时我们也是区块链开发团队。每天从全球超过500个优质信息源的近900篇内容中,寻找思考更具深度、梳理更为系统的内容,以最快的速度同步到中国市场提供决策辅助材料。