如何获得Cos和Tan函数的用户友好值?

时间:2014-08-18 16:00:05

标签: java android calculator trigonometry

我正在开发一个可以计算三角函数的android Calculator应用程序。我发现我的计算器显示:

Cos 90° = 6.123233995736766E-17 instead of  Cos 90° = 0
Cos 270° = -1.8369701987210297E-16 instead of Cos 270° = 0

Tan 180° = -1.2246467991473532E-16 instead of Tan 180° = 0
Tan 360° = -2.4492935982947064E-16 instead of Tan 360° = 0

我知道这些值实际上意味着0,但这些计算可能会让用户感到困惑。我还测试了0°,15°,18°,22.5°,30°,36°,45°,60°和72°的Cos和Tan值。他们似乎工作得很好。我正在使用Eclipse制作这个应用程序。

我的问题是“如何让我的计算器显示Cos和Tan函数的用户友好值?”。

这是我的Cos和Tan函数代码:

ImageButton btnCos;
ImageButton btnTan;
TextView txtDisplay;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btnCos = (ImageButton) findViewById(R.id.btnCos);
    btnTan = (ImageButton) findViewById(R.id.btnTan);
    txtDisplay = (TextView) findViewById(R.id.txtDisplay);

    btnCos.setOnClickListener(this);
    btnTan.setOnClickListener(this);

}

Double total = 0.0;

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub

if (v.getId() == R.id.btnCos) {
    if (txtDisplay.getText().equals("")) {
        txtDisplay.setText("");
    }
    else {
        total = Math.cos(Math.toRadians(Double.parseDouble(txtDisplay.getText().toString())));
        txtDisplay.setText("");
        txtDisplay.setText(txtDisplay.getText().toString() + total);
    }
}
else if (v.getId() == R.id.btnTan) {
    if (txtDisplay.getText().equals("")) {
        txtDisplay.setText("");
    }
    else {
        total = Math.tan(Math.toRadians(Double.parseDouble(txtDisplay.getText().toString())));
        txtDisplay.setText("");
        txtDisplay.setText(txtDisplay.getText().toString() + total);
    }
}

4 个答案:

答案 0 :(得分:3)

Java Math trig函数使用弧度。有一个效用函数,Math.toRadians(degrees)(你可能需要round() - 所以我相信你想要这样的东西,

System.out.println(Math.round(Math.cos(Math.toRadians(90))));

输出

0

答案 1 :(得分:3)

cos(90°)不是~6.123,它是~6.123E-17。这是一个非常小的数字。

这是由于浮点舍入。在SO和其他网站上有很多资源;我建议将floating-point-gui.de作为第一站。基本上,您不能将90°精确表示为有限精度浮点数,因此您实际上并不需要cos(90°)。你要求的数字的cos值非常接近到90°,因此答案非常接近为0。

类似的推理适用于其他结果。例如,tan(90°)是~1.633E16 - 一个非常大的数字 - 因为你要求的是一个非常接近90°的数字的tan,但不是那么。

答案 2 :(得分:2)

小数点后你可能看起来不够:6.123233995736766E-17 = 6.10 -17 ,几乎为零。

由于浮点具有这些错误,通常只会隐藏它们:通过格式化输出。

String.format("%0.3f", x);

另外,某些语言环境使用小数点逗号(实际上是ISO标准)。因此,您可能更喜欢使用DecimalFormat来解析和格式化数字。

答案 3 :(得分:0)

非常感谢。

通过更改

修改代码
if (txtDisplay.getText().equals("")) {
    txtDisplay.setText("");
}
else {
    total = Math.cos(Math.toRadians(Double.parseDouble(txtDisplay.getText().toString())));
    txtDisplay.setText("");
    txtDisplay.setText(txtDisplay.getText().toString() + total);
}

double value = Double.parseDouble(txtDisplay.getText().toString());
if (value % 90 == 0) {
    double total = 0.0;
    total = Math.round(Math.cos(Math.toRadians(Double.parseDouble(txtDisplay.getText().toString()))));
    txtDisplay.setText("");
    txtDisplay.setText(txtDisplay.getText().toString() + total);
}
else if (value % 60 == 0) {
    total = Math.floor(Math.cos(Math.toRadians(Double.parseDouble(txtDisplay.getText().toString())))) + 0.5;
    txtDisplay.setText("");
    txtDisplay.setText(txtDisplay.getText().toString() + total);
}
else {
    total = Math.cos(Math.toRadians(Double.parseDouble(txtDisplay.getText().toString())));
    txtDisplay.setText("");
    txtDisplay.setText(txtDisplay.getText().toString() + total);
}

并改变

if (txtDisplay.getText().equals("")) {
    txtDisplay.setText("");
}
else {
    total = Math.tan(Math.toRadians(Double.parseDouble(txtDisplay.getText().toString())));
    txtDisplay.setText("");
    txtDisplay.setText(txtDisplay.getText().toString() + total);
}

double value = Double.parseDouble(txtDisplay.getText().toString());
if (value % 180 != 0 && value % 90 == 0) {
    txtDisplay.setText("undefined");
}
else if (value % 45 == 0) {
    double total = 0.0;
    total = Math.round(Math.tan(Math.toRadians(Double.parseDouble(txtDisplay.getText().toString()))));
    txtDisplay.setText("");
    txtDisplay.setText(txtDisplay.getText().toString() + total);
}
else {
    total = Math.tan(Math.toRadians(Double.parseDouble(txtDisplay.getText().toString())));
    txtDisplay.setText("");
    txtDisplay.setText(txtDisplay.getText().toString() + total);
}

解决了我的问题。

所以,我的新代码是:

ImageButton btnCos;
ImageButton btnTan;
TextView txtDisplay;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btnCos = (ImageButton) findViewById(R.id.btnCos);
    btnTan = (ImageButton) findViewById(R.id.btnTan);
    txtDisplay = (TextView) findViewById(R.id.txtDisplay);

    btnCos.setOnClickListener(this);
    btnTan.setOnClickListener(this);

}

Double total = 0.0;

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub

    if (v.getId() == R.id.btnCos) {
        double value = Double.parseDouble(txtDisplay.getText().toString());
        if (value % 90 == 0) {
            double total = 0.0;
            total = Math.round(Math.cos(Math.toRadians(Double.parseDouble(txtDisplay.getText().toString()))));
            txtDisplay.setText("");
            txtDisplay.setText(txtDisplay.getText().toString() + total);
        }
        else if (value % 60 == 0) {
            total = Math.floor(Math.cos(Math.toRadians(Double.parseDouble(txtDisplay.getText().toString())))) + 0.5;
            txtDisplay.setText("");
            txtDisplay.setText(txtDisplay.getText().toString() + total);
        }
        else {
            total = Math.cos(Math.toRadians(Double.parseDouble(txtDisplay.getText().toString())));
            txtDisplay.setText("");
            txtDisplay.setText(txtDisplay.getText().toString() + total);
        }
    }
    else (v.getId() == R.id.btnTan) {
        double value = Double.parseDouble(txtDisplay.getText().toString());
        if (value % 180 != 0 && value % 90 == 0) {
            txtDisplay.setText("undefined");
        }
        else if (value % 45 == 0) {
            double total = 0.0;
            total = Math.round(Math.tan(Math.toRadians(Double.parseDouble(txtDisplay.getText().toString()))));
            txtDisplay.setText("");
            txtDisplay.setText(txtDisplay.getText().toString() + total);
        }
        else {
            total = Math.tan(Math.toRadians(Double.parseDouble(txtDisplay.getText().toString())));
            txtDisplay.setText("");
            txtDisplay.setText(txtDisplay.getText().toString() + total);
        }
    }