我正在写一个做很多事情的程序,但其中一个是将Celcius转换为Fahrenheit。在我这样做之后,我决定允许反过来,这就是我所做的。当我将Celcius转换为Fahrenheit时,我得到了正确的答案,但出于某种原因,我在将华氏温度转换为Celcius时得到的答案略有不同。这是我的代码:
String celcius = jTextArea3.getText();
String fahren = jTextArea7.getText();
if (fahren.equals("")) {
double tempFahr;
double Input = Double.parseDouble(jTextArea3.getText());
tempFahr = Input * 9 / 5 + 32;
jTextArea7.setText(tempFahr + "");
}
else
{
double tempCelc;
double Input = Double.parseDouble(jTextArea7.getText());
tempCelc = (Input -32) * 5 / 9;
jTextArea3.setText(tempCelc + "");
}
这是一个简单的代码,但我想知道它是否可能是我看不到的非常小的东西。我想这可能是我的公式,但我很确定它不是,我已经研究过了。有人可以帮忙吗?
我得到的答案的一个例子是: 1摄氏度= 33.8华氏度 33.8华氏度= 0.9999999999999984 Celcius
答案 0 :(得分:5)
因为Java使用浮点数的IEEE二进制表示,所以浮点计算几乎从不“精确”。问题是33.8无法准确表示,它在内部33.799999999999996或其他东西。当你将它转换回摄氏度时,你得到的数字远远小于1。
与往常一样,相关参考资料为What Every Computer Scientist Should Know About Floating-Point Arithmetic。
答案 1 :(得分:4)
@Greg是对的
你只需要进行一些舍入:
final int precision = 6 // try some different values here, from 2 to... 8?
jTextArea3.setText(String.format("%." + precision + "f", tempCelc));
无论如何 - 不要担心你的价值观很好,但要比较(或打印,这是当前的用例) 你需要一些epsilon / precision,因为 - 再次:浮点计算几乎从不“精确”。
答案 2 :(得分:2)
使用Double.toString()
(或其隐式等效项)时,浮点不准确性将非常明显。而是更喜欢String.format("%.3f", value)
或your choice of precision。
旁注:在Java中,无论您指定的数据类型如何,将整数除以整数都会产生整数。重构代码时要小心,因为看起来相似的东西可能无意中绕过结果中的因子。 (有关详细信息,请阅读this section of the Java Language Specification的第二段。)
double test = 3 / 2; // yields 2
double test = 3 / 2.0; // yields 1.5
答案 3 :(得分:1)
值的微小差异仅仅是浮点不准确的结果。十进制值无法表示为二进制中的精确值(计算机内部使用的是什么),导致10 ^ -16左右的极小差异。在this article中很好地介绍了这个主题(尽管使用Python)。