我不确定为什么一段时间后,这个程序开始输出无穷大

I'm not sure why after some time, this program starts to output infinity

我想编写一个程序,使用梯度下降法计算最佳拟合线。这是我的代码:

import java.util.ArrayList;
import java.io.*;
import java.util.Scanner;
class Main {
  public static double d0(double m, double b, ArrayList<Long> trueY) {
    double res = 0;
    for (int i = 0 ; i < trueY.size() ; i++) {
      res+=(m*i+b)-trueY.get(i);
    }
    res = res/trueY.size();
    return res;
  }
  public static double d1(double m, double b, ArrayList<Long> trueY) {
    double res = 0;
    for (int i = 0 ; i < trueY.size() ; i++) {
      res+=((m*i+b)-trueY.get(i))*i;
    }
    res = res/trueY.size();
    return res;
  }
  public static void main(String[] args) {
    ArrayList<Long> trueY = new ArrayList<Long>();
    try {
      File myObj = new File("digdelnums.txt");
      Scanner myReader = new Scanner(myObj);
      while (myReader.hasNextLine()) {
        long data = myReader.nextLong();
        trueY.add(data);
      }
      myReader.close();
    } catch (FileNotFoundException e) {
      System.out.println("An error occurred.");
      e.printStackTrace();
    }
    double alpha = 1;
    double theta1 = 0, theta0 = 0;
    double temp1 = theta1 - (alpha*d1(theta1, theta0, trueY));
    double temp0 = theta0 - (alpha*d0(theta1, theta0, trueY));
    /*
    System.out.print(temp0);
    System.out.print(" ");
    System.out.println(temp1);
    theta1 = temp1;
    theta0 = temp0;
    temp1 = theta1 - (alpha*d1(theta1, theta0, trueY));
    temp0 = theta0 - (alpha*d0(theta1, theta0, trueY));
    System.out.print(temp0);
    System.out.print(" ");
    System.out.println(temp1);
    theta1 = temp1;
    theta0 = temp0;
    temp1 = theta1 - (alpha*d1(theta1, theta0, trueY));
    temp0 = theta0 - (alpha*d0(theta1, theta0, trueY));
    System.out.print(temp0);
    System.out.print(" ");
    System.out.println(temp1);
    theta1 = temp1;
    theta0 = temp0;
    temp1 = theta1 - (alpha*d1(theta1, theta0, trueY));
    temp0 = theta0 - (alpha*d0(theta1, theta0, trueY));
    */
    while (!(theta0 == temp0 && theta1 == temp1)) {
      System.out.print(" temp0: ");
      System.out.print(temp0);
      System.out.print(" temp1: ");
      System.out.println(temp1);
      theta1 = temp1;
      theta0 = temp0;
      temp1 = alpha*d1(theta1, theta0, trueY);
      temp0 = alpha*d0(theta1, theta0, trueY);
    }
  }
}

唯一的问题是,在 while 循环的几次迭代之后,temp1 开始存储 Infinity。我意识到有人问了一些关于为什么程序 returns Infinity 的问题,但我一直找不到答案。我是 Java 的新手,如有任何帮助,我们将不胜感激。

以下是我得到的输出:

temp0: 3.316799084695052E8 temp1: 3.8386449054430206E11
 temp0: 3.333863100377265E14 temp1: 3.861723799932096E17
 temp0: 3.353910454100809E20 temp1: 3.884945309735452E23
 temp0: 3.374078355415694E26 temp1: 3.9083064562814664E29
 temp0: 3.3943675313588086E32 temp1: 3.931808079236908E35
 temp0: 3.414778711184791E38 temp1: 3.9554510233215225E41
 temp0: 3.4353126285334533E44 temp1: 3.979236138334556E47
 temp0: 3.4559700214561855E50 temp1: 4.0031642791853155E53
 temp0: 3.4767516324424656E56 temp1: 4.027236305923881E59
 temp0: 3.497658208446524E62 temp1: 4.051453083772042E65
 temp0: 3.518690500914227E68 temp1: 4.0758154831543767E71
 temp0: 3.539849265810076E74 temp1: 4.1003243797295477E77
 temp0: 3.5611352636443777E80 temp1: 4.1249806544217646E83
 temp0: 3.582549259500566E86 temp1: 4.149785193452459E89
 temp0: 3.604092023062723E92 temp1: 4.174738888372125E95
 temp0: 3.625764328643213E98 temp1: 4.199842636092383E101
 temp0: 3.647566955210562E104 temp1: 4.2250973389182087E107
 temp0: 3.669500686417421E110 temp1: 4.250503904580352E113
 temp0: 3.691566310628722E116 temp1: 4.276063246267989E119
 temp0: 3.713764620950058E122 temp1: 4.30177628266152E125
 temp0: 3.7360964152561505E128 temp1: 4.3276439379656014E131
 temp0: 3.758562496219541E134 temp1: 4.353667141942356E137
 temp0: 3.781163671339433E140 temp1: 4.379846829944819E143
 temp0: 3.8039007529707466E146 temp1: 4.406183942950514E149
 temp0: 3.8267745583532734E152 temp1: 4.432679427595307E155
 temp0: 3.8497859096410823E158 temp1: 4.459334236207427E161
 temp0: 3.872935633932059E164 temp1: 4.4861493268416895E167
 temp0: 3.8962245632976413E170 temp1: 4.513125663313925E173
 temp0: 3.919653534812707E176 temp1: 4.54026421523563E179
 temp0: 3.943223390585679E182 temp1: 4.5675659580488296E185
 temp0: 3.966934977788773E188 temp1: 4.595031873061107E191
 temp0: 3.9907891486885487E194 temp1: 4.622662947480914E197
 temp0: 4.014786760676322E200 temp1: 4.650460174453017E203
 temp0: 4.038928676299206E206 temp1: 4.67842455309422E209
 temp0: 4.063215763291015E212 temp1: 4.706557088529252E215
 temp0: 4.08764889460342E218 temp1: 4.734858791926927E221
 temp0: 4.1122289484374295E224 temp1: 4.763330680536456E227
 temp0: 4.13695680827486E230 temp1: 4.791973777724022E233
 temp0: 4.161833362910121E236 temp1: 4.820789113009571E239
 temp0: 4.1868595064821813E242 temp1: 4.849777722103811E245
 temp0: 4.212036138506666E248 temp1: 4.878940646945438E251
 temp0: 4.2373641639082515E254 temp1: 4.90827893573858E257
 temp0: 4.262844493053121E260 temp1: 4.9377936429904826E263
 temp0: 4.2884780417817274E266 temp1: 4.967485829549406E269
 temp0: 4.3142657314417016E272 temp1: 4.9973565626427493E275
 temp0: 4.34020848892096E278 temp1: 5.027406915915427E281
 temp0: 4.366307246681038E284 temp1: 5.0576379694684457E287
 temp0: 4.392562942790594E290 temp1: 5.0880508098977176E293
 temp0: 4.4189765209591106E296 temp1: 5.1186465303331416E299
 temp0: 4.445548930570854E302 temp1: Infinity
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
 temp0: NaN temp1: NaN
...

Java 中的 double 数据类型最多只能容纳 Double.MAX_VALUE(大约 1.7E308),而且您似乎很快就会超过该值。

如果您需要更大的值,您应该查看 BigDecimal class。