【问题标题】:Why does dividing by zero result in 9.223372E+18?为什么除以零会得到 9.223372E+18?
【发布时间】:2015-03-23 22:09:46
【问题描述】:

我正在制作一个 Android 计算器,当我除以零时得到 9.223372E+18。为什么它不显示 NaN 或崩溃?我认为它会导致 9.223372E+18 因为这是可能的最大双精度值,因为我要除以零并使用双精度数据类型。既然它会让用户感到困惑,我该如何解决这个问题?


回复评论

大家好,感谢您的所有回复。我很感激。我在下面发布了我的代码。

public class CFM extends ActionBarActivity {
Double cfm, ac, volume;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_cfm);

            EditText e1 = (EditText) findViewById(R.id.editText1);
            EditText e2 = (EditText) findViewById(R.id.editText2);
            TextView t1 = (TextView) findViewById(R.id.editText3);
            t1.setEnabled(false);
            t1.setFocusable(false);

            e1.addTextChangedListener(new TextWatcher() {

                public void afterTextChanged(Editable s) {
                }

                public void beforeTextChanged(CharSequence s, int start,
                                              int count, int after) {
                }

                public void onTextChanged(CharSequence s, int start,
                                          int before, int count) {
                    EditText e1 = (EditText)findViewById(R.id.editText1);
                    EditText e2 = (EditText)findViewById(R.id.editText2);
                    volume = Double.parseDouble(e1.getText().toString());
                    cfm = Double.parseDouble(e2.getText().toString());
                    TextView t1 = (TextView) findViewById(R.id.editText3);
                    ac = cfm * 60 / volume;
                    t1.setText(Double.toString((double) Math.round(ac * 100) / 100));
                }
            });


            e2.addTextChangedListener(new TextWatcher() {

                public void afterTextChanged(Editable s) {
                }

                public void beforeTextChanged(CharSequence s, int start,
                                              int count, int after) {
                }

                public void onTextChanged(CharSequence s, int start,
                                          int before, int count) {
                    EditText e1 = (EditText)findViewById(R.id.editText1);
                    EditText e2 = (EditText)findViewById(R.id.editText2);
                    volume = Double.parseDouble(e1.getText().toString());
                    cfm = Double.parseDouble(e2.getText().toString());
                    TextView t1 = (TextView) findViewById(R.id.editText3);
                    ac = cfm * 60 / volume;
                    t1.setText(Double.toString((double) Math.round(ac * 100) / 100));
                }
            });

}

【问题讨论】:

  • 请给出演示这个的示例代码。
  • 也许你应该在除法之前检查分母是否为零,如果是,使用你自己的NaN?
  • 9.223372E+17 怎么样?您是指仅按该数字的问题还是除以零的一般问题?
  • 9.223372E+18 甚至不接近最大可能的有限double 值(即~1.8E+308)。然而,它是最大的long 值。我认为您的代码中还有其他内容。你能发布一个简单(希望只有几行)完整的程序来演示这个问题吗?

标签: java android double


【解决方案1】:

9223372036854775807(大致为9.223372E+18)是最大可能的long 值。我可以看到除以零的唯一方法是如果你有一个long 类型的变量。例如,下面的代码打印9223372036854775807

long a = 1;
a /= 0.0; 
System.out.println(a);

当您将long 除以double 时,long 首先会转换为double,结果是double。任何正的double 除以0.0 得到Double.POSITIVE_INFINITY,所以1/0.0Double.POSITIVE_INFINITY。由于a 具有long 类型,因此将其转换回long,从而提供最大可能的long 值。

但是,我们需要查看您的代码才能了解为什么您有 long 类型的变量。

编辑

看过您的代码后,我现在意识到问题不是long 类型的变量,而是您对Math.round 的使用。这定义如下:

返回最接近参数的长整数,并向上取整。

Math.round 因此将Double.PositiveInfinity 向下舍入为9223372036854775807。将结果显示到小数点后 2 位的更好方法是这样的。

String result = Double.isInfinite(ac) || Double.isNaN(ac) ? "Error"
            : new BigDecimal(ac).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
t1.setText(result);

如果用户尝试除以零,这将打印"Error"

【讨论】:

  • 感谢pbabcdefp的解释。我在原始评论中添加了我的代码。我相信我将我的三个变量声明为 double,但我不是 100% 确定。是因为我使用 TextView 作为答案吗?
【解决方案2】:

在计算您的值时,使用检测机制查找该数字并显示“不能除以零”的错误。

要么,要么看看是否有一个异常处理程序来处理除以零。在此处查看抛出异常的示例:

How should I throw a divide by zero exception in Java without actually dividing by zero?

或在这里:Java division by zero doesnt throw an ArithmeticException - why?

或者正如 deyur 提到的,是的,您始终可以检查其中一个参数是否为零并以这种方式处理。

如果您还有其他问题,请分享核心代码 sn-ps,以便我们提供帮助。

【讨论】:

  • 一种更稳健的方法是在尝试除法之前检查除数的值以确保它不为零。
  • @deyur 为什么要打扰?这是其中一种情况,例如空值检查,最好只触发异常并在 UI 中捕获它。
  • 我不了解你,但我宁愿我的计算器告诉我我不能除以零,而不是崩溃并让我想知道发生了什么
  • 感谢分享 MikeDub 网站。我在原始评论中添加了我的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-02
  • 2012-12-17
  • 1970-01-01
相关资源
最近更新 更多