Solidity 中的数学(第 5 部分:指数和对数

news2024/9/29 19:20:52

   本文是关于在 Solidity 中进行数学运算的系列文章中的第五篇。这次的主题是:指数和对数

 

介绍

几个世纪以来,对数被用来简化计算。在电子计算器广泛普及之前,计算尺、基于对数的机械计算器是工程师职业的标志。

对数函数连同指数函数(指数函数是对数函数的倒数)允许将乘法转换为加法,更重要的是,可以将求幂转换为乘法。由于以下两个规则,这是可能的:

在对这些方程的左右部分取幂后,我们有:

请注意,这些公式适用于除那个以外的任意正基b,因此我们可以选择便于实现的基。

在本文中,我们将展示如何在 Solidity 中有效地实现以 2 为底的对数和指数函数,如何将这些以 2 为底的函数转换为相应的自然(以e为底)函数,以及这些函数在 DeFi 应用程序中的实际用例是什么.

所以本文的重点是指数和对数

对数

让我们从二进制(以 2 为底)对数开始。x的二进制对数是满足以下条件的值y

显然,x的值必须为正才能使y存在。

请注意,如果

然后

所以nx的二进制对数的整数部分。因此,我们的第一个问题是:

Solidity中如何计算二进制对数的整数部分?

剧透:向右移动并计数。

这是适用于正整数x的简单方法:

for (n = 0; x > 1; x >>= 1) n += 1;

虽然清晰简单,但这种方法非常昂贵,因为它的气体消耗为 O(n)。这是适用于 256 位正整数x的改进版本:

if (x >= 2**128) { x >>= 128; n += 128; }
if (x >= 2**64) { x >>= 64; n += 64; }
if (x >= 2**32) { x >>= 32; n += 32; }
if (x >= 2**16) { x >>= 16; n += 16; }
if (x >= 2**8) { x >>= 8; n += 8; }
if (x >= 2**4) { x >>= 4; n += 4; }
if (x >= 2**2) { x >>= 2; n += 2; }
if (x >= 2**1) { /* x >>= 1; */ n += 1; }

这种改进的实现在最坏的情况下消耗了大约 600 gas:比原始的、未优化的少 25 倍。

到目前为止还不错,但是

如果 X 是小数怎么办?

剧透:只需添加指数。

Solidity 语言的核心中没有小数,但是有几种方法可以模拟这些数字。让我们考虑其中两种方式:二进制定点和二进制浮点。两种方式都表示小数x,如下所示:

其中me是整数。值m称为尾数,e称为指数。二进制定点数和浮点数的区别在于,对于定点数,指数是预定义的常量,通常为负数,因此只需要存储尾数;而对于浮点数,指数是可变的,因此必须与尾数一起存储。

现在让我们注意,

因此,二进制定点数或浮点数的二进制对数可以计算为尾数加上指数的二进制对数。只要指数是整数,同样的公式也适用于对数的整数部分。

现在,当我们知道如何为整数部分提供资金时,

二进制对数的小数部分呢?

扰流板:正方形和一半。

nx的二进制对数的整数部分,那么对数的小数部分可以这样计算:

注意,只要

然后

因此,计算二进制对数的小数部分可以推导为计算 1(含)和 2(不含)之间数字的二进制对数。为了进行此计算,我们将使用以下两个规则:

这是编写的代码,好像 Solidity 本身就支持小数:

for (delta = 1; delta >= precision; delta /= 2) {
  if (x >= 2) { result += delta; x /= 2; }
  x *= x;
}

在每次迭代中,我们应用以前的规则:将 的值平方并将 的值x减半delta。如果在某个时刻 的值x变得大于或等于 2,那么我们将应用后一个规则:将 的值加起来deltaresult减半x。我们重复循环直到delta下降到期望值以下precision,因为继续计算不会对result.

不幸的是,Solidity 本身不支持分数,所以真正的代码看起来像这样:

for (delta = ONE;
     gte (delta, precision);
     delta = div (delta, TWO)) {
  if (gte (x, TWO)) {
    result = add (resukt, delta);
    x = div (x, TWO);
  }
  x = mul (x, x);
}

其中ONETWOaddmuldiv, 和gte是常数和函数,模拟某种小数和对它们的算术以实现 Solidity。

幸运的是,ABDK 库已准备好对 64.64 位二进制定点四精度二进制浮点数使用二进制对数实现。

现在,当我们知道如何计算二进制对数时,

自然对数和常用对数呢?

剧透:魔法因素。

为了计算自然对数(以e为底)和常用对数(以 10 为底),我们可以使用以下规则:

因此,

这里

是可以硬编码到实现中的神奇因素,不需要在运行时计算。

现在,当我们完成对数运算后,让我们切换到

指数

同样,让我们​​从以 2 为底的求幂开始,即计算

Solidity 有**权力的运营商,所以显而易见的解决方案是:

y = 2**x

但是,这仅适用于x的那些值,即整数和非负值。此外,这不是最有效的方法,因为使用移位操作会更便宜一些:

y = 1 << x

这种转变也可能有助于x的负值:

y = x >= 0 ? 1 << x : 1 >> -x

由于 Solidity 本身不支持分数,任何负 x 都会导致零结果,这没有多大意义。但是,如果我们将此处的整数 1 替换为 1 的定点表示,则这段代码将变得更加合理。

对于二进制浮点数就更简单了,因为在上面的公式中,y是一个二进制浮点数,尾数等于 1,指数等于x

到目前为止还不错,但是

如果 x 是小数怎么办?

剧透:倍增魔法因素。

让我们将x的小数值拆分为整数部分n和小数部分f

然后

f为二进制分数:

然后

注意:

神奇的因素,

可以预先计算,不需要在运行时计算:

这很好,但是

我们应该预先计算多少魔法因子?

扰流板:尽可能多的精度位。

对于二进制定点数,答案很明显,因为小数点后的二进制位数是固定的。所以。如果不动点的小数部分有 64 位,那么我们需要 64 个魔法因子。

对于二进制浮点数,事情要复杂一些,因为尾数m可能会被大的负指数e移到最右边。因此,此类浮点数的二进制表示形式如下所示:

幸运的是,对于任何介于 0 和 1 之间的f,确实有

所以如果f是上面显示的二进制表示的数字,那么

因此,如果所需的结果精度是M位,那么我们可以忽略f的二进制表示的那些位,这些位比点后的M个二进制位更远。这样我们最多需要预先计算M个魔法因子来计算指数。

可在ABDK 库源代码中找到二进制定点数和浮点数的基数 2 指数函数的即用型实现。

以 2 为底的指数很好,但是

任意基数的指数如何?

剧透:使用对数。

我们知道,对于任意正数x和任意正数b,以下情况成立:

因此,对于任意y

对于b =2 这给了我们:

由于我们已经知道如何计算以 2 为底的对数和指数函数,因此我们可以计算任意底数的指数函数。

该公式可用于有效地计算连续复利:

这里r是单个时间单位的利率,t是计算复利的时间间隔的长度。请注意,在固定利率的情况下,该值

可以只计算一次,可能是链下的,然后重复使用,这将使这个公式更加有效。

结论

在本文中,我们展示了如何在 Solidity 中针对二进制定点数和浮点数有效地计算以 2 为底的对数和指数函数。

我们还描述了如何通过 base-2 函数实现基于任意的对数和指数函数。

我们介绍了使用对数和指数函数有效实现的连续复利计算的真实用例。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/174465.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【matplotlib】21.多图合并【python3、numpy、pandas、matplotlib完结】

#【matplotlib】21.多图合并 2023.1.20 python3、numpy、pandas、matplotlib完结 新年快乐&#xff01;&#xff01; 21.1 多合一显示 21.1.1 均匀分布 方法很简单 就是一张图 分几块 第一张占几块 从哪开始&#xff1b;第二张… plt.subplot() # 打开一个窗口 import ma…

Redis数据类型简介

目录 1、字符串(Strings) 1.1、底层实现 1.2、基本命令 1.3、应用场景 2、列表(Lists) 2.1、底层实现 2.2、基本命令 2.3、应用场景 3、集合(Sets) 3.1、底层实现 3.2、基本命令 3.3、应用场景 4、哈希(Hashes) 4.1、底层实现 4.2、基本命令 4.3、应用场景 5、…

Caché数据库简要记录

前一阵子&#xff0c;实施的小伙伴找过来问我用过 Cach 数据库吗&#xff1f;我当时有点懵&#xff1f;难道是 redis、memcached 之流&#xff1f;后来我特意去搜索了一下&#xff0c;还真是有一款数据库叫做 Cach Database。 这里做一下简单的记录吧&#xff0c;Cach 在医疗系…

Mine Goose Duck 0.1版本发布

我本次制作了一款MC版的Goose Goose Duck模组&#xff0c;游戏版本是Forge 1.19.2。 1.身份物品 熟悉鹅鸭杀的朋友都知道游戏中含有许多的身份&#xff0c;有好人、坏人、中立三个阵营&#xff0c;本次我加入了原作中的一些基本角色&#xff1a; 1.警长 你可以杀死怪物但错…

DFS(三)电话号码的字母组合

数组版本 哈希版本&#xff1a; 一、17. 电话号码的字母组合 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 示例 1&#x…

Elasticsearch7.8.0版本高级查询——范围查询文档

目录一、初始化文档数据二、范围查询文档2.1、概述2.2、示例一、初始化文档数据 在 Postman 中&#xff0c;向 ES 服务器发 POST 请求 &#xff1a;http://localhost:9200/user/_doc/1&#xff0c;请求体内容为&#xff1a; {"name":"张三","age"…

Git的安装与使用

目录 一、简介 1. Git 是什么&#xff1f; 2. 集中式和分布式 二、Git 环境搭建 1. Linux 下安装 2. Windows 下安装 三、创建版本库 四、把文件添加到版本库 1. 添加并提交 2. 仓库状态 3. 版本回退 &#xff08;1&#xff09;查看提交日志 &#xff08;2&#xff0…

量化交易-因子有效性分析

量化交易-因子有效性分析一、 因子的 IC 分析2. 信息系数3. 举例4. 因子处理4.1 去极值4.2 标准化4.3 市值中性化一、 因子的 IC 分析 判断因子与收益的相关性强度 分析结果 因子平均收益IC meanIC stdIC > 0.02&#xff1a;IC大约0.02的比例&#xff0c;越大越严格IR&…

leetcode刷题记录总结-1. 数组

文章目录一、二分查找[704. 二分查找](https://leetcode.cn/problems/binary-search/)题解小结[35. 搜索插入位置](https://leetcode.cn/problems/search-insert-position/)题解1&#xff1a;暴力解法题解2&#xff1a;二分法[34. 在排序数组中查找元素的第一个和最后一个位置]…

Day865.基础架构 -MySQL实战

基础架构&#xff1a;一条SQL查询语句是如何执行的 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的关于基础架构&#xff1a;一条SQL查询语句是如何执行的的内容。 经常说&#xff0c;看一个事儿千万不要直接陷入细节里&#xff0c;应该先鸟瞰其全貌&#xff0c;这样能够…

01-使用Camera Raw滤镜调色

1.需求展示 点击下载图片素材 原图 调色后, 具有电影感 2.操作步骤 1.打开原图 1.我使用的是ps2018, 打开原图, 图层名字可以自定义 2.拷贝底片建立一个新图层 养成好习惯, 每种操作都建立新图层来进行, 这样如果修坏了, 直接把该图层删除就行了, 还原图片比较快捷 3…

[QMT]03-让QMT支持从Tushare获取数据

QMT安装python第三方库为了兼容性&#xff0c;需要本地使用python3.6.8版本&#xff0c;因为刚刚下载的QMT python版本就是3.6.8.如果你本地有其他python版本的话&#xff0c;建议使用虚拟环境操作。这样不会影响你原有的python版本以及已经安装的第三方库。因为一机装多版本的…

Java设计模式-中介模式/中介模式具体怎么使用,使用场景又是什么

继续整理记录这段时间来的收获&#xff0c;详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用&#xff01; 6.8 中介者模式 6.8.1 定义 调停模式&#xff0c;定义一个中介角色来封装一系列对象的之间交互&#xff0c;使元有对象之间的耦合松散&#xff0c;且可以独立改变…

2023年春节祝福第二弹——送你一只守护兔,让它温暖每一个你【html5 css3】画会动的小兔子,炫酷充电,字体特效

2023年春节祝福第二弹 送你一只守护兔&#xff0c;让它温暖每一个你&#xff01; 【html5 css3】画一只会动的兔子 目录 一、送你一只守护兔&#xff0c;效果图 二、前言 三、代码解释及部分特效教程 &#xff08;1&#xff09;、css3 立体字 &#xff08;2&#xff09;…

普中科技MicroPython基于esp32的基础教程-01

课程链接 3.5-Python基础--代码注释_哔哩哔哩_bilibili 学习目的 复习和加深对Python的学习和使用&#xff0c;将Python的使用融汇于硬件使用中。因此笔记记录的内容都是我之前遗忘的或者重要的知识点&#xff0c;选择性记录视频笔记&#xff0c;在开发的过程中对于遗忘的知识…

基于Power BI的终端产品销售ABC分析

一、原理 ABC分析&#xff0c;是由帕累托法则演化而来&#xff0c;一般认为A类产品带来70%的收入&#xff0c;B类产品带来20%的收入&#xff0c;C类产品带来10%的收入&#xff0c;所以ABC分析又称70/20/10分析。 二、数据源 某终端《8~10月商品月台帐》 问题&#xff1a; 1…

计算机网络——UDP与TCP

一、运输层的作用 运输层在整个网络体系结构中位于面向通信部分的最高层&#xff0c;同时也是用户功能中的最低层。它提供的是应用进程间的逻辑通信。所谓逻辑通信&#xff0c;指的是它屏蔽了下层网络的细节&#xff0c;使得进程看见的就是好像在两个运输层实体之间有一条端到…

二分、复杂度、动态数组、哈希表

1.二分法 不一定一定有序&#xff0c;比如找局部最小值就可以不有序 有序数组中找到num 用对数器生成随机数组来校验find()方法是否正确 public class Code01_BSExist {//有序数组中找到num//arr保证有序public static boolean find(int[] arr, int num) {if (arr null || …

1594_AURIX_TC275_PMU_应用提示1

全部学习汇总&#xff1a; GreyZhang/g_TC275: happy hacking for TC275! (github.com) 这一页主要是描述了当前的PMU版本与之前就版本相比之下的变更&#xff0c;对于第一次接触了解这个模块来说&#xff0c;其实了解前面的基本特性就好了。而这个差异&#xff0c;没有细看的必…

2023年网络安全比赛--Linux渗透测试中职组(超详细)

一、竞赛时间 180分钟 共计3小时 二、竞赛阶段 1.通过本地PC中渗透测试平台Kali对靶机场景进行系统服务及版本扫描渗透测试,并将该操作显示结果中Apache服务对应的版本信息字符串作为Flag值提交; 2.通过本地PC中渗透测试平台Kali对靶机场景进行渗透测试,将该场景/var/www/ht…