Question
Do arithmetic division, if it is a cyclic decimal, the part of the loop should be enclosed in parentheses.
Solution
In simple words, this question is actually a simulation of our division process.
First, let ’s talk about what process we want to simulate, taking 20/11
as an example.
The quotient obtained for the first time is the integer part, denoted as integer
. We can directly use division between two ints.
1 | integer = 20 / 11 = 1 |
Then let’s recall the process of division.
As shown in the figure below, the quotient
is 1
, and the remainder
is 9
. To get the remainder
in the program, we can use numerator - quotient * denominator
.
1 | remainder = 20 - 1 * 11 = 9 |
Next we multiply the remainder
by 10
as the new numerator
, and continue to use 11
as the denominator
. Then get the quotient
and the new remainder
.
So calculate 90/11
.
Then repeat the above process, multiply the remainder
by 10
as the new numerator
, and continue to use 11
as the denominator
. Then get the quotient
and the new remainder
.
So calculate 20/11
.
Then repeat the above process again, multiply the remainder
by 10
as the new numerator
, and continue to use 11
as the denominator
. Then get the quotient
and the new remainder
.
So calculate 90/11
.
So when does it end?
- The
remainder
is 0, indicating that there is no cyclic decimal. - At first, I felt that as long as there are repeated
quotient
(not considering the integer part number, which is the first 1 in the above example), it can be considered that there is a cyclic decimal.
In the above example, 8
appears for the second time, so it will not be calculated further. The decimal part of the loop is the position that repeats from the previous appearance of current number to the previous position, which is 81
. So the final result is 1.(81)
.
However there is a counterexample as below:
Although there are repeated 8
s, the end result is not 8
cycles. Obviously next time it will be 40/17
, and quotient
is 2
. The reason is that the numerator
corresponding to the two quotients 8
are not the same. The first is 150
and the second is 140
.
Therefore, in order to judge whether there is a cyclic decimal, we should not judge whether there is a repeated quotient, but rather whether there is a repeated dividend.
Therefore, in order to determine whether there is a cyclic decimal, we should not judge whether there is a repeated quotient
, but rather whether there is a repeated numerator
.
To record quotient
, we will record the integer part and the decimal part separately. Because the decimal part has to accumulate records, For example, the first quotient
is 1, and the second quotient
is 2. We can multiply the previous quotient
by 10
and add the new quotient
. That is, 1 * 10 + 2 = 12
, when the third quotient
5
comes, it is 12 * 10 + 5 = 125
.
But for the above example 1/17
, the first quotient
is 0
, and the second quotient
is 5
. If the above recording method is used, 5
is recorded instead of 05
. In addition, if there are too many parts of the quotient
, overflow will occur, so we need to record the quotient
with String
, and a new quotient
can be added to the String
each time.
Another question is how to determine whether there are duplicate quotients
?
Quite simply, using a HashMap
, key records the numerator
that have occurred, and value records where the quotient
appears, so that when repeated dividends
occur, we can immediately know what the fractional part of the loop is by value.
The last question, we only considered the example of positive numbers divided by positive numbers. What about positive numbers divided by negative numbers or negative numbers divided by negative numbers? Just like we did on paper, first determine the sign of the quotient
, and then convert both the numerator
and the denominator
to positive numbers.
The above operation will cause a problem. In java, for int
type, the minimum value of negative number is -2147483648
, the maximum value of positive number is 2147483647
, and -2147483648
cannot be converted into a positive number.
The problem of overflow is actually not the key to this problem, so we can simply use the long
data type to store the number.
1 | public String fractionToDecimal(int numerator, int denominator) { |