Java 检查函数的极限无穷大

Java 检查函数的极限无穷大,java,math,junit,Java,Math,Junit,几周前,我写了一份试卷。第一项任务是找到具有给定属性的函数的正确近似值: 我必须用我为属性编写的测试来检查每个近似值。属性2、3和4没有问题。但我不知道如何使用Java编写的JUnit测试检查属性1。我的方法是这样做: @Test void test1() { Double x = 0.01; Double res = underTest.apply(x); for(int i = 0; i < 100000; ++i) { x = rnd(0,

几周前,我写了一份试卷。第一项任务是找到具有给定属性的函数的正确近似值:

我必须用我为属性编写的测试来检查每个近似值。属性2、3和4没有问题。但我不知道如何使用Java编写的JUnit测试检查属性1。我的方法是这样做:

@Test
void test1() {
    Double x = 0.01;
    Double res = underTest.apply(x);

    for(int i = 0; i < 100000; ++i) {
        x = rnd(0, x);
        Double lastRes = res;

        res = underTest.apply(x);

        assertTrue(res <= lastRes);
    }
}
@测试
void test1(){
双x=0.01;
双精度=测试不足。应用(x);
对于(int i=0;i<100000;++i){
x=rnd(0,x);
双lastRes=res;
res=测试不足。应用(x);
资产真实性(res)
有没有办法检查属性1

琐碎?不,当然不是。微积分是关于在无穷远/无限接近任何特定点时发生的事情——基本算术在尝试将一个越来越小的数字除以一个越来越小的范围时陷入困境,而基本算术不能做“0除以0”

计算机就像这里的基本算术,或者至少,你在粘贴的代码中应用了基本算术,让计算机做实际的微积分比你在这里做的要复杂得多。就像,多年的编程经验要求更复杂;我非常怀疑你应该写几十万沙行的代码,以建立一个完整的计算机数学平台,写这个测试,当然

更一般地说,你似乎是在一种观念下工作,即测试证明了一切

事实并非如此。测试无法证明正确性,就像科学无法证明任何东西一样,它们只能反驳(并且可以建立更加坚实的基础和确认,任何理性的人通常认为这是足够的,因此他们会认为重力定律将成立,即使没有证据也永远不会成立)

一个测试只能证明你有一个bug,它永远不能证明你没有

因此,您可以在这里做的任何事情都只是灰色场景:您可以让此测试捕获更多的场景,其中您知道
测试不足的
算法不正确,但不可能捕获所有场景

您粘贴的内容已经很有用:此测试证明,当您使用越来越接近0的双值时,您的测试将确保函数的输出变得越来越小。这是有价值的。您似乎认为此特定的灰色阴影对您来说不够暗。您希望显示它非常接近无穷大

这是…你的选择。你不能证明它是无穷大的,因为计算机就像基本的算术一样,有一些近似值

在这里你可以做的不多:是的,你可以测试最后的
res
值是否小于-1000000。你甚至可以测试它是否是负无穷大,但不能保证这是正确的;一个定义为“当输入从正端变为0时,输出将趋向于零”的函数“负无穷大”可以自由地这样做,只适用于非常微小的输入,以至于double根本无法表示它(计算机并不神奇;双精度需要64位,也就是说,
double
最多只能代表2^64个唯一的数字。2^64是一个非常大的数字,但与“所有数字都可以想象”的双维无穷大概念相比,它是无任何东西)(在0和1之间有无限数量的数字,而且在整个数字行中也有无限数量的此类数字)。因此,有大量非常微小的数字,
double
根本无法表示

为了你自己的理智,在单元测试中使用随机性是个坏主意,对于“单元测试”这个词的一些定义来说,字面上是不正确的(有些人认为单元测试必须是可靠的,否则就不能将其视为单元测试,如果你看看“单元测试”的实际用途,这并不是一个疯狂的想法:让测试环境自动运行单元测试,重复和几乎连续地运行,以便在som出现时尽快停止eone打破了一个。如果CI服务器每天运行1819次单元测试,如果纯粹是随机的,每20k次就有一次失败,那么它会变得非常恼人;然后它会认为是最近的提交造成的,而且据我所知,没有一个框架会重复多次单元测试。最后,如果你远离这个概念,编程效果最好证明和冷硬定义,并朝着“做社区认为事情意味着什么”的方向发展。对于单元测试,这意味着:不要使用随机性)

有没有办法检查属性1

琐碎?不,当然不是。微积分是关于在无穷远/无限接近任何特定点时发生的事情——基本算术在尝试将一个越来越小的数字除以一个越来越小的范围时陷入困境,而基本算术不能做“0除以0”

计算机就像这里的基本算术,或者至少,你在粘贴的代码中应用了基本算术,让计算机做实际的微积分比你在这里做的要复杂得多。就像,多年的编程经验要求更复杂;我非常怀疑你应该写几十万沙行的代码,以建立一个完整的计算机数学平台,写这个测试,当然

更一般地说,你似乎是在一种观念下工作,即测试证明了一切

事实并非如此。测试无法证明正确性,就像科学无法证明任何东西一样,它们只能反驳(并且可以建立更加坚实的基础和确认,任何理性的人通常认为这是足够的,因此他们会认为重力定律是成立的,即使没有证据证明
System.out.println(Double.MIN_VALUE);
System.out.println(Math.log(Double.MIN_VALUE));
System.out.println(Math.log(Double.MIN_VALUE) < -1000);

// prints
4.9E-324
-744.4400719213812
false