Gauss algorithm diary

Boy Genius

Most of the students may have heard about a well-known story. A primary school teacher, in order to allow the students to stop noisy, gives a data problem 1 + 2 + 3 + ... + 100 =? Originally I thought I could make them quiet twenty or thirty minutes, and the results less than one minute, there is a child out of a show of hands to answer, the teacher casually looked at the answer, never expected that turned out to be correct.

The children only 9 years old, he is Gaussian.

 

Secret diary

Gauss had a good habit: keep a diary anyway. His diary has a unique place, he never specified date, but instead by an integer, such as: 4210

Later, people know, that date is an integer that represents the day of the first few days after birth Gauss. This is perhaps a good habit, it always remind the owner: the day and the past day, how much time can be wasted for it?

Gauss was born: April 30, 1777. In the diary marked with an important theorem Gauss found: 5343, and therefore can be calculated that day is: December 15, 1791. That day marked the diary Gauss Ph.D.: 8113. Now please calculate the date Gaussian Ph.D.?

 

Problem-solving ideas

Let's look at an abstract problem, in essence, is required to take a certain period of a day of n the future, which is what month what day?

Scheme I: Method traversal cycle

Relatively easy to think of the way is to walk, cycle n times, we can deduce the date n days, and we have to try.

public  static  void Calc ( int year, int month The, int Day, int n-) { 

        for ( int I = 0; I <n-; I ++ ) { 
// day by day through Day
++ ;
// if it is too late to need reset the date, month +1
IF (Day> getMonthLastDay (year, month the)) { Day = 1 ; month the ++ ;
// If you had to end, month and date need to be reset at the same time, Year +1
IF (month the > 12 is ) {
month The
=. 1; Day =. 1 ; year ++ ; } } } System.out.println (n- + "days after the date is:" + year + "-" + month The + "-" + Day); }

Known conditions into the first, performing calc (1777,4,30,5343) the main function; 

Can get results for the December 16, 1791, and December 15, 1791 on the subject of a difference of day, this is what causes it?

Reflect can detect Gaussian birthday on this day actually count as the first day, that is when we are brought into the process need to pass April 29, 1777

     calc (1777,4,29,5343); operating results is December 15, 1791

The calc (1777,4,29,8113); operating results was July 16, 1799, one can imagine Gauss had obtained a doctorate at the age of 22, the real bloomer.

 

Option Two: use tool for law

When jdk8 provides us with a series of very friendly and date api, so that we solve this problem, you can quickly get the answers.

// create a Gaussian day before the date of birth 
LocalDate DATE = LocalDate.of (1777,4,29 );
// call to increase the number of days of methods to directly obtain the date n days after System.out.println (date.plusDays (
8113 ));

 

compare plan

 Now we have to write their own programs, as well as provide program jdk, then the question is, what kind of program implementation faster, better efficiency it?

long start = System.currentTimeMillis();
calc(1777, 4, 29, 8113);
long cost = System.currentTimeMillis() - start;
System.out.println("耗时" + cost);

System.out.println("===========");

start = System.currentTimeMillis();
//日期工具 jdk8 joda time
LocalDate date = LocalDate.of(1777, 4, 29);
System.out.println(date.plusDays(8113));
cost = System.currentTimeMillis() - start;
System.out.println("耗时" + cost);

We milliseconds tool to test, get the results as follows

 Note that this time unit is ms, the actual difference between the two schemes is about 0.1s.

Fast implementation of your glasses drop it, we wrote it myself realize even greater than jdk provided, this is why?

 

Source code analysis

We deeply realize LocalDate look like, what is the difference and achieve our own?

    public the LocalDate. plusDays ( Long daysToAdd) {
         IF (daysToAdd == 0 ) {
             return  the this ; 
        } 
// addExact is a simple adder
// toEpochDay () represents the year in which the epoch, a computer year January 1970 1, where the current day is calculated from the date of the year
// current number of days after n days from the date of the first year of current date + n = number of days from the day of the year
Long mjDay = Math.addExact (toEpochDay (), daysToAdd );
date n days from the first year // ofEpochDay (int n) is calculated
return LocalDate.ofEpochDay (mjDay); }

Then click into toEpochDay () look

public long toEpochDay() {
        long y = year;
        long m = month;
        long total = 0;
        total += 365 * y;
        if (y >= 0) {
            total += (y + 3) / 4 - (y + 99) / 100 + (y + 399) / 400;
        } else {
            total -= y / -4 - y / -100 + y / -400;
        }
        total += ((367 * m - 362) / 12);
        total += day - 1;
        if (m > 2) {
            total--;
            if (isLeapYear() == false) {
                total--;
            }
        }
        return total - DAYS_0000_TO_1970;
    }

We can see, this method is calculated by a formula, but ofEpochDay () is also true, so we can put a simple tool for the French equivalent formula.

 

to sum up

Why robin faster than formula method, let's stretch this issue. When you want to calculate the date after a few more days, and how both performance?

We compute 8,113,333 days after the date, round-robin time-consuming and time-consuming formula method can be found basically the same, at around 0.1s. And then it increased to 81,133,333 days, you can clearly see the formula method remains in 0.1s, and time-consuming method of recycling becomes more than 1s, a substantial increase.

This shows that after increasing the number of computing, time-consuming round-robin will grow into a slash, and time-consuming method of formula remained on the horizontal lines, which is the trade-off jdk designers do. On our own terms, under different scenarios, you can choose different implementations, there is no best, only the most suitable, you get to it?

Guess you like

Origin www.cnblogs.com/ruoyuBlog/p/11840208.html