比较一个双数与零 [英] Comparing a double against zero

查看:163
本文介绍了比较一个双数与零的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Java的新手,我一直在试图实现一个算法来找到立方体的根。当我计算判别式并尝试检查它在哪里下降到零时,会出现问题。



如果运行它并输入数字1 -5 8 -4 ,输出如下:

  1 -5 8 -4 
p = -0.333333,q = 0.074074
disc1 = 0.001372,disc2 = -0.001372
discriminant = 0.00000000000000001236
判别大于零。

我知道问题出现是因为使用双打的计算不准确。通常情况下,判别式应为0,但最终为0.00000000000000001236。



我的问题是,避免这种情况的最佳方法是什么?我应该检查一下这个数字是否在零点附近的epsilon附近?还是有更好的和更精确的方式?



提前谢谢你的答案。

  import java.util.Scanner; 

class Cubical {
public static void main(String [] args){
//声明变量。
double a,b,c,d,p,q,gamma,discriminant;

扫描仪userInput =新扫描仪(System.in);
a = userInput.nextDouble();
b = userInput.nextDouble();
c = userInput.nextDouble();
d = userInput.nextDouble();

//计算p和q。
p =(3 * a * c - b * b)/(3 * a * a);
q =(2 * b * b * b)/(27 * a * a * a) - (b * c)/(3 * a * a)+ d / a;

//计算判别式。
判别式=(q / 2)*(q / 2)+(p / 3)*(p / 3)*(p / 3)

//只是看看这些值。
System.out.printf(p =%f,q =%f\\\
disc1 =%f,disc2 =%f\\\
discriminant =%。20f \\\
,p,q,(q / 2)*(q / 2),(p / 3)*(p / 3)*(p / 3),(q / 2)*(q / 2)+(p / *(p / 3));

if(discriminant> 0){
System.out.println(判别大于零);
}
if(discriminant == 0){
System.out.println(判别等于零);
}
if(discriminant< 0){
System.out.println(Discriminant is less than 0);
}
}
}


解决方案

最简单的epsilon检查是

  if(Math.abs(value)< ERROR)

一个更复杂的值与值成比例

  if(Math.abs(value)< ERROR_FACTOR * Math.max(Math.abs(a),Math.abs(b)))
/ pre>




在具体情况下,您可以:

  if(discriminant> ERROR){
System.out.println(判别大于零);
} else if(discriminant< -ERROR){
System.out.println(Discriminant is less than 0);
} else {
System.out.println(判别等于零);
}


I'm new to Java and I've been trying to implement an algorithm for finding the roots of a cubical equation. The problem arises when I calculate the discriminant and try to check where it falls relative to zero.

If you run it and enter the numbers "1 -5 8 -4", the output is as follows:

1 -5 8 -4
p=-0.333333, q=0.074074
disc1=0.001372, disc2=-0.001372
discriminant=0.00000000000000001236
Discriminant is greater than zero.

I know the problem arises because the calculations with doubles are not precise. Normally the discriminant should be 0, but it ends up being something like 0.00000000000000001236.

My question is, what is the best way to avoid this? Should I check if the number falls between an epsilon neighborhood of zero? Or is there a better and more precise way?

Thank you in advance for your answers.

import java.util.Scanner;

class Cubical {
    public static void main(String[] args) {
        // Declare the variables.
        double a, b, c, d, p, q, gamma, discriminant;

        Scanner userInput = new Scanner(System.in);
        a = userInput.nextDouble();
        b = userInput.nextDouble();
        c = userInput.nextDouble();     
        d = userInput.nextDouble();

        // Calculate p and q.
        p = (3*a*c - b*b) / (3*a*a);
        q = (2*b*b*b) / (27*a*a*a) - (b*c) / (3*a*a) + d/a;

        // Calculate the discriminant.
        discriminant = (q/2)*(q/2) + (p/3)*(p/3)*(p/3);

        // Just to see the values.
        System.out.printf("p=%f, q=%f\ndisc1=%f, disc2=%f\ndiscriminant=%.20f\n", p, q, (q/2)*(q/2), (p/3)*(p/3)*(p/3), (q/2)*(q/2) + (p/3)*(p/3)*(p/3));

        if (discriminant > 0) {
            System.out.println("Discriminant is greater than zero.");
        }
        if (discriminant == 0) {
            System.out.println("Discriminant is equal to zero.");
        }
        if (discriminant < 0) {
            System.out.println("Discriminant is less than zero.");
        }
    }
}

解决方案

The simplest epsilon check is

if(Math.abs(value) < ERROR)

a more complex one is proportional to the value

if(Math.abs(value) < ERROR_FACTOR * Math.max(Math.abs(a), Math.abs(b)))


In your specific case you can:

if (discriminant > ERROR) {
    System.out.println("Discriminant is greater than zero.");
} else if (discriminant < -ERROR) {
    System.out.println("Discriminant is less than zero.");
} else {
    System.out.println("Discriminant is equal to zero.");
}

这篇关于比较一个双数与零的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆