1. 引言

通常,有两种对编程语言的改进。第一种是让困难的事情变得简单,第二种是让不可能的事情变为可能。本文介绍的是任意精度算术,它属于第二类:使在ABAP中原本不可能的事情成为可能。

过去已经可以在ABAP中使用INT8或DECFLOAT34数据类型进行非常大的数字计算,但还不能进行任意精度的计算。使用这两种数据类型,也有溢出的风险。

尽管DECFLOAT34可以对非常大的数字进行操作,但其精度仅为34位。这意味着当你进行更复杂的计算时,可能会得到错误的结果。典型的问题是当加减不同大小类别的数字时,例如:

larger_number + smaller_number - larger_number = 0

原因是大数没有足够的精度来反映小数的加法。如果你再减去大数,会得到零。小并不意味着数字真的很小,只是它比较大的数字小得多。所以在这种情况下,10000可能是小的。

许多编程语言提供了任意精度算术的能力。例如,Java有BigInteger和BigDecimal类,Python的整数数据类型默认为任意精度,而C#也提供了一个BigInteger数据类型。C++语言有著名的GMP和MPFR库用于任意精度算术。

英文原文:New classes for arbitrary precision arithmetic in ABAP

本文链接:https://www.cnblogs.com/hhelibeb/p/17868032.html

2. 不同种类的任意精度算术

通常,编程语言中有三种任意精度算术库。第一种是任意精度整数算术。这允许用任意大的整数进行计算。可以假想这种类型的数字为INT∞。当然,数字并非真的可以任意长,但受限于系统的主内存的容量。然而,对于每个实际应用,你可以假想结果的数字为无穷大。

这种库的典型质量标准是乘法指令的速度和时间复杂度。经典的教科书乘法复杂度为log(N)²,因为你需要将第一个数的每一位与第二个数的每一位相乘。令人惊奇的是,有更有效的乘法算法,最简单的就是众所周知的Karatsuba算法。

一般来说,任意精度整数算术的库也提供了一些数论操作的可能性,例如,确定质数和计算GCD(最大公约数)。

下一种类型的任意精度数字是任意精度有理数。任意精度有理数是两个任意精度整数的商a / b。注意,每个具有有限小数的十进制数都是一个有理数,例如,1.01 = 101 / 100。因此,每个固定大小的ABAP类型P/DEC的十进制数都可以写成一个有理数。由于精度仍然是有限的,同样的,每个DECFLOAT34类型的数字也可以写成一个有理数。

有理数在这个意义上是复杂的,即分数必须被简化,例如,2 / 4 = 1 / 2。因此,实现有理数要求有一个好的GCD算法。

有理数算术库不提供像EXP或LOG这样的超越函数,甚至其他简单的操作,如平方根。这是因为有理数的指数和对数只在非常特定的情况下也是有理数。平方根也是如此。

对于平方根,有一个简单的技巧可以计算任意数量的数字,只需使用整数算术。然而,对于超越函数,没有类似的技巧。

为了计算超越函数,你需要一个任意精度浮点(或实数)算术库。这些库可以计算具有任意给定精度的实数。例如,你可以决定用100,1000,或10000位来计算2的对数。

3. 在ABAP中的任意精度算术

在过去,ABAP没有任何形式的任意精度算术的能力。随着2308版本和793内核的发布,ABAP引入了两个新的类:CL_ABAP_BIGINTCL_ABAP_RATIONAL,用于实现任意精度的整数和有理数算术。另外,虽然CL_ABAP_RATIONAL在内部实现中使用了任意精度的实数算术来进行其转换到DECFLOAT34,但ABAP尚未公开任意精度的实数算术功能。

这两个类都是侵入式的,这意味着如果你向一个数添加另一个数,你不会得到一个新的实例,而是原来的实例会被改变。考虑以下编码:

result_bigint = bigint->add( other_bigint )

这会改变bigint实例并返回一个自我引用以允许链接。因此,result_bigint和bigint实际上是同一个实例。这样做是为了确保高性能。当然,也有一个clone()方法,可以生成bigint的副本,允许非侵入性操作。例如,你可以写成:

result_bigint = bigint->clone()->add( other_bigint )

这两个类都已经发布到ABAP Cloud,因此可以在Steampunk、Embedded Steampunk和SAP S/4HANA Cloud中使用。(译者注:虽然我没验证,但可以想象OP版本的7.58也会有

CL_ABAP_BIGINT类具有以下特性:

  • 基本的算术操作,如加法、减法、乘法和带余数的除法
  • 快速克隆操作
  • 快速乘法
  • 高级操作,如最大公约数和整数平方根
  • 数论操作,如质数确定、MOD、POWMOD和MOD_INVERSE
  • 序列化到/从XML/JSON
  • 带千位分隔符的外部表示转换
  • 启用共享内存(仅限非ABAP Cloud)
  • 转换到/从STRING和到DECFLOAT34
  • 适用于ABAP Cloud

CL_ABAP_RATIONAL类几乎具有与CL_ABAP_BIGINT类相同的特性,但是它并未包含那些对有理数来说没有意义的数论函数。

4. 体验如何?

通常,数字计算是使用DECFLOAT34或INT8等内置数据类型进行的。对于相同的任务使用类似乎看似有些不寻常,但实际上非常可读。一个好例子是计算整数平方根的算法,也就是floor(sqrt(n)),如下所示:

class compute_sqrt definition.
public section.
methods compute_sqrt importing number type ref to cl_abap_bigint
returning value(sqrt) type ref to cl_abap_bigint.
endclass. class compute_sqrt implementation.
method compute_sqrt.
data y type ref to cl_abap_bigint.
final(bits) = number->get_number_of_bits( ).
data(x) = cl_abap_bigint=>factory_from_int4( 1 )->mul_by_two_power( ( bits + 2 ) / 2 ).
do.
y = x->clone( )->add( number->clone( )->div( x )-quotient )->div_by_two_power( 1 ).
if y->is_larger_or_equal( x ).
exit.
endif.
x = y.
enddo.
return x.
endmethod.
endclass. start-of-selection.
data(result) = new compute_sqrt( )->compute_sqrt(
cl_abap_bigint=>factory_from_string( `129341967194712394612956129461294861619246` ) ).
cl_demo_output=>display( result->to_string( ) ).

5. 演示程序

任意精度整数库的一个简单演示是RSA算法的实现。RSA是一种被广泛使用的公钥/私钥加密。RSA的每个实现都使用大于一百或一千位精度的大数

有一个演示类CL_DEMO_BIGINT_RSA,以及一个演示报表程序DEMO_BIGINT_RSA,它根据给定的位大小生成公钥/私钥,并使用它加密一条小消息。以前是不可能在纯ABAP中生成RSA公钥/私钥的。以下是纯ABAP实现效果:

还有另一个在CL_DEMO_BIGINT_SQRTDEMO_BIGINT_SQRT中的演示,用于计算自然数的平方根的任意多位数。

6. 何时使用任意精度算术?

可以在以下情况中使用任意精度算术:

  • 真的需要大于34位的大数,因为你的算法需要它。典型的例子就是RSA算法。
  • 有非常大或非常小的数字的计算,不想有任何溢出或下溢。或者,有未知大小的数字的计算,不想关心溢出或下溢。
  • 有复杂的计算,不想关心舍入误差。别忘了:只要坚持使用基本的算术运算,对于任意精度算术,永远不会有任何舍入误差。
  • 使用一些数论算法,如质数检查或模反。

7. ABAP关键字文档和发布说明

可以在以下位置找到更多关于此主题的信息:

参考:ABAP 7.58更新概览

ABAP 7.58 中支持任意精度算术的新类的更多相关文章

  1. 学习PHP中的任意精度扩展函数

    今天来学习的是关于数学方面的第一个扩展.对于数学操作来说,无非就是那些各种各样的数学运算,当然,整个程序软件的开发过程中,数学运算也是最基础最根本的东西之一.不管你是学得什么专业,到最后基本上都会要学 ...

  2. PHP中操作任意精度大小的GMP扩展学习

    对于各类开发语言来说,整数都有一个最大的位数,如果超过位数就无法显示或者操作了.其实,这也是一种精度越界之后产生的精度丢失问题.在我们的 PHP 代码中,最大的整数非常大,我们可以通过 PHP_INT ...

  3. 有意思的RTL函数RegisterClass(在持久化中,你生成的一个新类的对象,系统并不知道他是如何来的,因此需要你注册)good

    例子1:Delphi中使用纯正的面向对象方法(这个例子最直接) Delphi的VCL技术使很多程序员能够非常快速的入门:程序员门只要简单的拖动再加上少量的几个Pascal语句,呵呵,一个可以运行得非常 ...

  4. 支持无限精度无限大数的类BigNumber实现

    介绍 本篇是MathAssist的第二篇,在前言中粗略地展示了MathAssist的“计算和证明”能力,本篇开始将详细介绍其实现原理. 从计算开始说起,要实现任意大数的计算器首先得有一个类支持大数运算 ...

  5. 如何在MQ中实现支持任意延迟的消息?

    什么是定时消息和延迟消息? 定时消息:Producer 将消息发送到 MQ 服务端,但并不期望这条消息立马投递,而是推迟到在当前时间点之后的某一个时间投递到 Consumer 进行消费,该消息即定时消 ...

  6. LINUX任意精度计算器BC用法

    [用途说明] Bash内置了对整数四则运算的支持,但是并不支持浮点运算,而bc命令可以很方便的进行浮点运算,当然整数运算也不再话下.手册页上说bc是An arbitrary precision cal ...

  7. 【OpenGL(SharpGL)】支持任意相机可平移缩放的轨迹球实现

    [OpenGL(SharpGL)]支持任意相机可平移缩放的轨迹球 (本文PDF版在这里.) 在3D程序中,轨迹球(ArcBall)可以让你只用鼠标来控制模型(旋转),便于观察.在这里(http://w ...

  8. Devrama Slider - 支持任意 HTML 的内容滑块

    Devrama Slider 是一个图片滑块,支持很多特色功能.除了支持图片滑动,其它的 HTML 内容也支持.主要特色:响应式.图片预加载.图片延迟加载.进度条.自定义导航栏和控制按钮等等. 在线演 ...

  9. pojg2744找一个最长的字符串x,使得对于已经给出的字符串中的任意一个y,x或者是y的子串,或者x中的字符反序之后得到的新字符串是y的子串。

    http://poj.grids.cn/practice/2744 描述现在有一些由英文字符组成的大小写敏感的字符串,你的任务是找到一个最长的字符串x,使得对于已经给出的字符串中的任意一个y,x或者是 ...

  10. EntityFramework中支持BulkInsert扩展

    EntityFramework中支持BulkInsert扩展 本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 前言 很显然,你应该不至于使用 Ent ...

随机推荐

  1. springboot3接入nacos

    参考:https://blog.csdn.net/qinguan111/article/details/132877842(连接不上nacos) https://verytoolz.com/yaml- ...

  2. HarmonyOS账号服务,畅行鸿蒙生态所有应用与服务

    账号对于用户来说并不陌生,在购买新设备或者使用新应用的时候,用户常常会被引导注册或者登录账号,账号就是用户在这些设备或应用内的通行证.根据华为上半年的一项统计,整体上中国网民人均下载App量在68个, ...

  3. 华为会员开放服务(Membership Kit),助力移动应用快速建设会员生态

    会员开放服务(Membership Kit)是华为面向开发者提供的券码开放能力,开发者可以通过Membership Kit开展灵活多样的营销活动,助力开发者建设会员生态,实现用户运营与增量创收的目标. ...

  4. HMS Core 3D精准室内定位技术,打造“店铺级”出行体验

    2022年4月28日,在华为折叠旗舰及全场景新品发布上,华为Mate Xs 2折叠屏手机搭载由HMS Core定位服务(Location Kit)提供的3D精准室内定位技术,为用户提供了"店 ...

  5. Qt数据结构-QString二:QString的arg能不能像Python的format一样使用

    常规QString拼接字符串我们是这样写的 QString s = QString("My name is %1, age %2").arg("zhangsan" ...

  6. XRebel工具激活方式,亲测有效

    首先进入生成 GUID 的网址:https://www.guidgen.com/ 用这个网址 + 生成的 GUID 激活:https://jrebel.qekang.com/ 例如:https://j ...

  7. HarmonyOS传感器开发指南

      HarmonyOS系统传感器是应用访问底层硬件传感器的一种设备抽象概念.开发者根据传感器提供的Sensor接口,可以查询设备上的传感器,订阅传感器数据,并根据传感器数据定制相应的算法开发各类应用, ...

  8. 【课程汇总】Hello HarmonyOS系列课程,手把手带你零基础入门

    HarmonyOS是面向未来.面向全场景的新一代智能终端操作系统,为不同设备的智能化.互联与协同提供了统一的语言,给人们带来简洁.流畅.连续.安全可靠的全场景交互体验. 初识HarmonyOS的开发者 ...

  9. ThinkPHP6.x 使用指南

    PHP 版本:PHP 8.1.0 框架版本:ThinkPHP 6 编辑工具:PHPStorm 2021.3.3 系统环境:Windows 10 0x01 概述 (1)简介 ThinkPHP 框架简称 ...

  10. pytest接口自动化搭建经验

    前言:目前公司的主要产品是一个web类型的产品:需要做一些自动化,目前的想法是只做接口自动化,不做ui的一个自动化,目前的思路是先对主流程做正常校验,后期再对每一个接口做校验: 一.版本信息: pyt ...