Vipanchith Reddy
Vipanchith Reddy

Reputation: 484

How to get user friendly values of Cos and Tan functions?

I am working on an android Calculator application which can calculate trigonometric functions. I find that my Calculator shows:

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

I know these values actually mean 0 but these calulations might be a little confusing to the users. I have also tested the Cos and Tan values of 0°, 15°, 18°, 22.5°, 30°, 36°, 45°, 60° and 72°. They seem to work fine. I am using Eclipse to make this app.

My question is "How do i get my Calculator to show user friendly values of Cos and Tan functions?".

This is my Code for Cos and Tan function:

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);
    }
}

Upvotes: 1

Views: 805

Answers (4)

Vipanchith Reddy
Vipanchith Reddy

Reputation: 484

Thank you very much.

Modifying the Code by changing

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);
}

to

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);
}

and changing

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);
}

to

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);
}

solved my problem.

So, my new Code is :

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);
        }
    }

Upvotes: 0

Joop Eggen
Joop Eggen

Reputation: 109593

You probably did not look far enough after the decimal point: 6.123233995736766E-17 = 6.10-17, almost zero.

As floating point has these errors, one in general merely hides them: by formating the output.

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

As an aside, some locales use a decimal comma (in fact that is the ISO standard). So you might prefer to use DecimalFormat to parse and format numbers.

Upvotes: 2

yshavit
yshavit

Reputation: 43401

cos(90°) is not ~6.123, it's ~6.123E-17. That's an extremely small number.

This is due to floating-point rounding. There are many resources out there on SO and other sites; I recommend floating-point-gui.de as a first stop. Basically, you can't exactly represent 90° as a finite-precision floating-point number, so you're not actually asking for cos(90°). You're asking for cos of a number that's very close to 90°, and the answer is therefore very close to 0.

Similar reasoning holds true for the other results. For instance, tan(90°) is ~1.633E16 -- a very large number -- because you're asking for the tan of a number that's very close to 90°, but not exactly that.

Upvotes: 3

Elliott Frisch
Elliott Frisch

Reputation: 201497

Java Math trig functions use radians. There is a utility function, Math.toRadians(degrees) (and you will probably need to round() - so I believe you want something like this,

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

Output is

0

Upvotes: 3

Related Questions