Les nombres rationnels (les nombres qui peuvent être représentés sous forme d'entiers / entiers) peuvent toujours être représentés par des fractions finies ou circulaires. Au contraire, les fractions finies et les fractions circulaires peuvent toujours être exprimées sous forme de nombres rationnels.
Exemple 3/4 = 0.75 1/7 = 0.142857142857... = 0.(142857) (La partie circulante de la fraction circulaire est appelée le nœud circulaire, et elle est représentée par des points sur le premier et le dernier nombre du nœud circulaire. Les clauses circulaires sont placées entre parenthèses. )
Je voulais exprimer un nombre rationnel arbitraire comme une fraction qui ne se coupe pas au milieu, j'ai donc créé une classe qui représente un nombre rationnel, Comme l'une des méthodes, j'ai créé une méthode qui "met en évidence une notation fractionnaire qui peut être exprimée comme une clause circulaire à partir d'un nombre rationnel". De plus, comme l'une des méthodes d'usine, j'ai créé une méthode qui reçoit une chaîne de caractères fractionnaires comprenant une expression de clause circulaire et la convertit en un nombre rationnel.
Les champs de la classe des nombres rationnels sont molécule: molécule, type long dénominateur: dénominateur, type long Et dit. De plus, les éléments de code sont unifiés et la molécule l'a, et elle est transformée en une classe invariante sous la forme de fractions irréductibles. Si c'est un entier, j'ai décidé de l'avoir sous la forme de 1 dans le dénominateur.
Transformez des nombres rationnels en fractions
public String toDecimalString() {
//S'il s'agit d'un entier, il sera affiché tel quel
if (denominator == 1L)
return String.valueOf(molecule);
//Divisez dans la manière d'écrire. Tout d'abord, retirez la partie entière
LinkedHashMap<Long, Long> restAndDigit = new LinkedHashMap<>();
long integer = Math.abs(molecule) / denominator;
long remind = Math.abs(molecule) % denominator;
//Répétez la division jusqu'à ce que le même reste que le reste mentionné ci-dessus apparaisse ou soit divisible.
while (!restAndDigit.containsKey(remind) && remind != 0L) {
long r = remind * 10L;
restAndDigit.put(remind, r / denominator);
remind = r % denominator;
}
StringBuilder builder = new StringBuilder();
if (molecule < 0L)
builder.append('-');
builder.append(integer).append('.');
//S'il est divisible, affichez tous les chiffres côte à côte
if (remind == 0L) {
restAndDigit.values().forEach(builder::append);
return builder.toString();
}
Iterator<Map.Entry<Long, Long>> iterator = restAndDigit.entrySet().iterator();
Map.Entry<Long, Long> temp;
while (!(temp = iterator.next()).getKey().equals(remind)) {
builder.append(temp.getValue());
}
builder.append('(').append(temp.getValue());
iterator.forEachRemaining(e -> builder.append(e.getValue()));
return builder.append(')').toString();
}
Conversion de la notation fractionnaire en nombres rationnels
public static Fraction2 parseDecimal(String str) {
Matcher matcher = Pattern.compile("(-?\\d+\\.\\d*)(\\(\\d+\\))?").matcher(str);
if (!matcher.matches())
throw new NumberFormatException("Illegal input : " + str);
BigDecimal decimal = new BigDecimal(matcher.group(1));
if (matcher.group(2) == null)
return fromDecimal(decimal);
BigInteger m1 = decimal.unscaledValue();
BigInteger d1 = TEN.pow(decimal.scale());
BigDecimal decimal2 = new BigDecimal(matcher.group().replaceAll("[\\(\\)]", ""));
BigInteger m2 = decimal2.unscaledValue();
BigInteger d2 = TEN.pow(decimal2.scale());
//Une autre méthode pour créer un nombre rationnel en utilisant BigInteger
return fromBigInteger(m2.subtract(m1), d2.subtract(d1));
}
À l'origine, la molécule du dénominateur a été fabriquée avec BigInteger et laissée sans surveillance, mais je l'ai réécrite en pensant longtemps qu '"un grand nombre ne viendra pas à la molécule du dénominateur", mais je m'inquiète du débordement dû à l'addition et à la multiplication Je me suis souvenu que j'utilisais BigInteger car il était difficile de démarrer orz