Java自定义数字接口-平方根
问题是在通用数值接口中定义平方根算法问题的策略方法。我知道在不同的条件下,解决这个问题的算法是存在的。我对以下算法感兴趣:Java自定义数字接口-平方根,java,numerical-methods,Java,Numerical Methods,问题是在通用数值接口中定义平方根算法问题的策略方法。我知道在不同的条件下,解决这个问题的算法是存在的。我对以下算法感兴趣: 仅使用选定的函数解决问题 不在乎被操纵的对象是整数、浮点还是其他,只要这些对象可以被添加、多重化和对置 如果输入为完全平方,则返回精确解 由于区分的微妙性,为了清晰起见,我将以非常详细的方式定义这个问题。当心墙上的文字 假设有一个Java接口常量,其中包含以下抽象方法,我们将其称为基函数: C添加(C a) C减法(ca) C乘(ca) C[]分隔符和维护符(cb)
- 仅使用选定的函数解决问题李>
- 不在乎被操纵的对象是整数、浮点还是其他,只要这些对象可以被添加、多重化和对置李>
- 如果输入为完全平方,则返回精确解
假设有一个Java接口
常量
,其中包含以下抽象方法,我们将其称为基函数:
C添加(C a)代码>
C减法(ca)代码>
C乘(ca)代码>
C[]分隔符和维护符(cb)代码>
C additiveInverse()代码>
C乘法逆()代码>
C additiveIdentity()代码>
C乘法实体()代码>
int比较(C arg1)代码>
静态
或默认
实现:例如,除法和余数(cb)代码>和比较(C arg1)代码>允许为更大的公约数、贝佐特标识等创建算法
现在假设我们的接口有一个用于求幂的默认方法:
public default C pow(int n){
if(n < 0) return this.additiveInverse().pow(-n);
if(n == 0) return additiveIdentity();
int m = n;
C output = this;
while(m > 1)
{
if(m%2 == 0) output = output.multiply(output);
else output = this.multiply(output.multiply(output));
m = m/2;
}
return output;
}
公共默认C功率(int n){
如果(n<0),则返回此.additiveInverse().pow(-n);
如果(n==0)返回additiveIdentity();
int m=n;
C输出=此;
而(m>1)
{
如果(m%2==0)输出=output.multiply(输出);
else output=this.multiply(输出.multiply(输出));
m=m/2;
}
返回输出;
}
目标是定义两个名为C root(int n)
和C maximumerroallowed()
的default
方法,以便:
x.equals(y.pow(n))
表示x.root(n).equals(y)
李>
C根(int-n)代码>实际上是实现的仅使用基本函数和从基本函数创建的方法李>
- 该接口仍然可以应用于任何类型的数字,包括但不限于整数和浮点
this.root(n).pow(n).compareTo(maximumerroallowed())==-1
对于所有this
这样this.root(n)=空
,即任何最终近似值的误差小于C maximumErrorAllowed()
李>
可能吗?如果是的话,计算复杂度的评估方法和内容是什么?我花了一些时间为Java开发一个自定义数字接口,这非常困难——这是我使用Java时最令人失望的经历之一
问题是你必须从头开始——你不能真正重用Java中的任何东西,所以如果你想实现int、float、long、biginger、rational、Complex和Vector,你必须为每个类自己实现所有方法,然后不要指望数学包会有多大帮助
实现“组合”类,比如由两种“通用”浮点类型组成的“Complex”类,或者由两种通用整数类型组成的“Rational”类,就变得特别糟糕
数学运算符是正确的——这可能特别令人沮丧
我让它工作得相当好的方法是用Java实现类,然后用Groovy编写一些更高级的东西。如果操作命名正确,Groovy就可以选择它们,就像您的类实现“.plus()”一样,那么Groovy将允许您执行instance1+instance2
IIRC由于是动态的,Groovy通常能够很好地处理跨类片段,比如说,如果你说的是Complex+Integer,你可以提供从整数到复数的转换,Groovy会将Integer升级到复数来执行操作并返回复数
Groovy与Java是非常可互换的,您通常只需重命名一个Java类“.Groovy”并编译它,它就会工作,所以这是一个非常好的折衷方案
这是很久以前的事了,现在你可能会在你的“数字”接口中使用Java 8的默认方法,这可能会使实现一些类变得更容易,但可能没有帮助。我必须再试一次才能找到答案,而且我不确定我是否想重新打开那些可能的蠕虫
可能吗?如果是,如何进行
理论上,是的。对于root()
,有一些近似算法,例如。但是,您可能会遇到精度方面的问题,您可能希望逐个解决(即使用整数查找表)。因此,我建议不要在接口中使用默认实现
计算复杂性的估计是什么
这也取决于您的数字类型,并且取决于您的精度。对于整数,您可以使用查找表创建一个实现,其复杂性为O(1)
如果您想对操作本身的复杂性有一个更好的答案,您可能需要检查。可能很难有效地实现this==this.pow(n).root(n)
;您是否满意this.equals(this.pow(n).root(n))
?this==this.pow(n).root(n)
对于int和double,如果this
为负数且n
为2的倍数,则int和double都为假。那是expec吗