Fractions en Java
Mathématiquement, les fractions sont les parties ou sections de valeurs. Lorsqu’un objet est brisé également dans des proportions définies, la valeur formée s’appelle une fraction. Les fractions sont classées en nombres rationnels et irrationnels.
Dans le langage de programmation Java, il existe un privilège d’effectuer diverses opérations sur des fractions telles que des procédures mathématiques. On peut additionner, soustraire, multiplier et diviser sur les nombres fractionnaires.
Vous trouverez ci-dessous le bloc de code qui illustre les opérations de nombre rationnel dans la classe définie par l’utilisateur.
import java.math.BigInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RationalNumber {
public final static RationalNumber ZERO = new RationalNumber(BigInteger.ZERO, BigInteger.ONE);
private final BigInteger numerator, denominator;
private RationalNumber(BigInteger numerator, BigInteger denominator) {
this.numerator = numerator;
this.denominator = denominator;
}
private static RationalNumber canonical(
BigInteger numerator, BigInteger denominator, boolean checkGcd) {
if (denominator.signum() == 0) {
throw new IllegalArgumentException("denominator is zero");
}
if (numerator.signum() == 0) {
return ZERO;
}
if (denominator.signum() < 0) {
numerator = numerator.negate();
denominator = denominator.negate();
}
if (checkGcd) {
BigInteger gcd = numerator.gcd(denominator);
if (!gcd.equals(BigInteger.ONE)) {
numerator = numerator.divide(gcd);
denominator = denominator.divide(gcd);
}
}
return new RationalNumber(numerator, denominator);
}
public static RationalNumber getInstance(long numerator, long denominator) {
return canonical(new BigInteger("" + numerator), new BigInteger("" + denominator), true);
}
public static RationalNumber valueOf(String s) {
Pattern p = Pattern.compile("(-?\\d+)(?:.(\\d+)?)?0*(?:e(-?\\d+))?");
Matcher m = p.matcher(s);
if (!m.matches()) {
throw new IllegalArgumentException("Unknown format '" + s + "'");
}
String whole = m.group(1);
String decimal = m.group(2);
String exponent = m.group(3);
String n = whole;
if (decimal != null) {
n += decimal;
}
BigInteger numerator = new BigInteger(n);
int exp = exponent == null ? 0 : Integer.valueOf(exponent);
int decimalPlaces = decimal == null ? 0 : decimal.length();
exp -= decimalPlaces;
BigInteger denominator;
if (exp < 0) {
denominator = BigInteger.TEN.pow(-exp);
} else {
numerator = numerator.multiply(BigInteger.TEN.pow(exp));
denominator = BigInteger.ONE;
}
return canonical(numerator, denominator, true);
}
public static void main(String[] args) {
RationalNumber r1 = RationalNumber.valueOf("3.14e4");
RationalNumber r2 = RationalNumber.getInstance(111, 7);
convert("r1", r1);
convert("r2", r2);
convert("r1 + r2", r1.add(r2));
convert("r1 - r2", r1.subtract(r2));
convert("r1 * r2", r1.multiply(r2));
convert("r1 / r2", r1.divide(r2));
convert("r2 ^ 2", r2.pow(2));
}
public static void convert(String name, RationalNumber r) {
System.out.printf("%s = %s%n", name, r);
System.out.printf("%s.negate() = %s%n", name, r.negate());
System.out.printf("%s.invert() = %s%n", name, r.invert());
System.out.printf("%s.intValue() = %,d%n", name, r.intValue());
System.out.printf("%s.longValue() = %,d%n", name, r.longValue());
System.out.printf("%s.floatValue() = %,f%n", name, r.floatValue());
System.out.printf("%s.doubleValue() = %,f%n", name, r.doubleValue());
System.out.println();
}
public RationalNumber add(RationalNumber o) {
if (o.numerator.signum() == 0) {
return this;
} else if (numerator.signum() == 0) {
return o;
} else if (denominator.equals(o.denominator)) {
return new RationalNumber(numerator.add(o.numerator), denominator);
} else {
return canonical(numerator.multiply(o.denominator).add(o.numerator.multiply(denominator)),
denominator.multiply(o.denominator), true);
}
}
public RationalNumber multiply(RationalNumber o) {
if (numerator.signum() == 0 || o.numerator.signum() == 0) {
return ZERO;
} else if (numerator.equals(o.denominator)) {
return canonical(o.numerator, denominator, true);
} else if (o.numerator.equals(denominator)) {
return canonical(numerator, o.denominator, true);
} else if (numerator.negate().equals(o.denominator)) {
return canonical(o.numerator.negate(), denominator, true);
} else if (o.numerator.negate().equals(denominator)) {
return canonical(numerator.negate(), o.denominator, true);
} else {
return canonical(numerator.multiply(o.numerator), denominator.multiply(o.denominator), true);
}
}
public boolean isInteger() {
return numerator.signum() == 0 || denominator.equals(BigInteger.ONE);
}
public RationalNumber negate() {
return new RationalNumber(numerator.negate(), denominator);
}
public RationalNumber invert() {
return canonical(denominator, numerator, false);
}
public RationalNumber pow(int exp) {
return canonical(numerator.pow(exp), denominator.pow(exp), true);
}
public RationalNumber subtract(RationalNumber o) {
return add(o.negate());
}
public RationalNumber divide(RationalNumber o) {
return multiply(o.invert());
}
public int intValue() {
return isInteger() ? numerator.intValue() : numerator.divide(denominator).intValue();
}
public long longValue() {
return isInteger() ? numerator.longValue() : numerator.divide(denominator).longValue();
}
public float floatValue() {
return (float) doubleValue();
}
public double doubleValue() {
return isInteger() ? numerator.doubleValue()
: numerator.doubleValue() / denominator.doubleValue();
}
@Override
public String toString() {
return isInteger() ? String.format("%,d", numerator)
: String.format("%,d / %,d", numerator, denominator);
}
}
Dans le programme ci-dessus, l’exécution démarre à partir de la méthode main
. Tout d’abord, un nombre rationnel est initialisé à l’aide de la fonction statique valueOf()
définie dans la classe. Il prend une valeur de chaîne et effectue des manipulations sur la chaîne d’entrée.
Il renvoie un RationalNumber
du type défini par l’utilisateur. La fonction vérifie d’abord une chaîne d’entrée avec des validations et des modèles appropriés. La chaîne d’entrée est séparée en exposant, décimal et toute la partie. Ces valeurs brisées individuelles se combinent pour former un nombre rationnel.
Une autre façon de créer un nombre rationnel consiste à utiliser une fonction d’usine statique instanceOf()
. La méthode appelle en interne la fonction canonical
, qui appelle un constructeur privé de la classe. Le constructeur sépare et définit les valeurs du numérateur et du dénominateur pour une instance spécifique. Par forme canonique, on entend simplement la forme de représentation standard du nombre rationnel.
Dans le cas donné, p/q
est la forme standard ou canonique où q!=0
devrait toujours être vrai. La méthode a la logique écrite pour satisfaire les conditions de base d’un nombre rationnel. Il vérifie séparément le signe du numérateur et du dénominateur et effectue des opérations. Il vérifie les valeurs du dénominateur ; si c’est zéro, l’opération lève une exception. Il vérifie également le plus grand commun diviseur ou pgcd
dans les valeurs du numérateur et du dénominateur. La fonction gcd
est présente dans la classe BigInteger
qui renvoie une valeur BigInteger
.
Pour aller de l’avant, la méthode convert
est appelée, en passant la première instance de nombre rationnel qui est créée. Cette méthode fait également appel à sept fonctions différentes sur l’instance nombre rationnel qui est passée.
Ci-dessous, vous comprendrez mieux chacune de ces méthodes :
- Imprimer le nombre rationnel dans le flux d’impression. Généralement, chaque fois qu’une instance est imprimée, la méthode par défaut
toString
est appelée. La méthode imprime le nom de la classe suivi de la représentation hexadécimale de l’emplacement mémoire. Mais ici, la fonction est surchargée pour donner une autre implémentation qui représente le nombre sous la formep/q
. - La fonction
negate
niera en interne le nombre rationnel en appelant la méthodenegate
de la classeBigInteger
. Il ajoutera un signe moins avant le nombre rationnel. - La fonction invert appelle en interne la méthode
canonical
avec une seule différence. Il passe en interne le troisième paramètrecheckGcd
comme false. Lorsque la valeur d’entrée est booléenne true, la logique de la méthode simplifie le nombre rationnel en divisant la fraction par son plus grand diviseur commun. Mais dans ce cas, il s’agit d’inverser sans simplification. - La fonction
intValue
vérifie d’abord si l’instance est une valeurInteger
. LesIntegers
sont des nombres qui peuvent être positifs, négatifs ou nuls, mais ne peuvent pas être des fractions. Ainsi, en interne, il appelle la méthodedivide
sur le numérateur et le dénominateur. La méthode est donnée dans la classeBigInteger
et retourne une valeurBigInteger
. Il lève égalementArithmeticException
lorsque le dénominateur trouve une valeur zéro. La valeur renvoyée est transformée en une valeurint
à l’aide de la fonctionintValue
. - La fonction
longValue
appelle en interne la fonction de division et parse la sortieBigInteger
en un type de donnéeslong
. - La fonction
floatValue
fournit la valeur à virgule flottante du nombre rationnel. Et de même que la fonctiondoubleValue()
, qui transtype la sortie dans le type de donnéesDouble
.
L’ensemble du processus est appelé sur une instance initiale de nombre rationnel qui est l’instance r1
. Une séquence similaire est à nouveau répétée et est imprimée pour l’instance rationnelle r2
.
Opérations mathématiques pour les fractions en Java
Maintenant, les opérations arithmétiques d’addition, de soustraction, de division, de multiplication et de puissance nécessitent deux opérandes pour l’évaluation. Examinons donc les méthodes en détail ci-dessous :
- La fonction
add
vérifie d’abord les valeurs du numérateur si elles sont positives, négatives ou nulles. S’il est différent de zéro, il vérifie si les dénominateurs des deux nombres rationnels sont les mêmes. S’il est identique, il ajoute la valeur du numérateur et renvoie le nombre rationnel formé. Sinon, s’il n’est pas trouvé similaire, il définit la logique pour l’addition rationnelle de nombres. - La méthode
subtract
appelle en interne la méthodeadd
après avoir nié la deuxième instance de nombre rationnel passée. - La méthode
multiply
a une logique assez complexe en interne. Il vérifie si le numérateur est zéro de l’un des nombres rationnels, il renvoie la sortie sous forme de valeur zéro. Si ce n’est pas zéro, il vérifie le numérateur avec le dénominateur de l’un ou l’autre ensemble. C’est-à-dire que le numérateurr1
est vérifié avec le dénominateurr2
et vice-versa. Lorsqu’aucune condition ne correspond, le numérateur der1
est multiplié par le numérateur d’instancer2
, et les dénominateurs des deux sont multipliés. Enfin, il appelle la fonctionmultiply
de la classeBigInteger
pour effectuer la multiplication. - La fonction
divide
inversera l’instance passée et appellera en interne la fonctionmultiply
en utilisant la première instance. - La dernière est la fonction
pow
qui évalue la seconde puissance de l’instancer2
. L’implémentation depow
est définie dans la classeBigInteger
qui prend l’exposant pour l’évaluation. La méthode lève l’exceptionArithmeticException
lorsque l’exposant est une valeur négative.
Vous trouverez ci-dessous la sortie du code complexe donné ci-dessus :
r1 = 31, 400 r1.negate() = -31, 400 r1.invert() = 1 / 31, 400 r1.intValue() = 31,
400 r1.longValue() = 31, 400 r1.floatValue() = 31, 400.000000 r1.doubleValue() = 31,
400.000000
r2 = 111 / 7 r2.negate() = -111 / 7 r2.invert() = 7 / 111 r2.intValue() = 15 r2.longValue() =
15 r2.floatValue() = 15.857142 r2.doubleValue() = 15.857143
r1
+ r2 = 219,
911 / 7 r1 + r2.negate() = -219, 911 / 7 r1 + r2.invert() = 7 / 219,
911 r1 + r2.intValue() = 31, 415 r1 + r2.longValue() = 31,
415 r1 + r2.floatValue() = 31, 415.857422 r1 + r2.doubleValue() = 31,
415.857143
r1
- r2 = 219,
689 / 7 r1 - r2.negate() = -219, 689 / 7 r1 - r2.invert() = 7 / 219,
689 r1 - r2.intValue() = 31, 384 r1 - r2.longValue() = 31,
384 r1 - r2.floatValue() = 31, 384.142578 r1 - r2.doubleValue() = 31,
384.142857
r1* r2 = 3,
485, 400 / 7 r1* r2.negate() = -3, 485, 400 / 7 r1* r2.invert() = 7 / 3, 485,
400 r1* r2.intValue() = 497, 914 r1* r2.longValue() = 497,
914 r1* r2.floatValue() = 497, 914.281250 r1* r2.doubleValue() = 497,
914.285714
r1
/ r2 = 219,
800 / 111 r1 / r2.negate() = -219, 800 / 111 r1 / r2.invert() = 111 / 219,
800 r1 / r2.intValue() = 1, 980 r1 / r2.longValue() = 1, 980 r1 / r2.floatValue() = 1,
980.180176 r1 / r2.doubleValue() = 1,
980.180180
r2
^ 2 = 12,
321 / 49 r2 ^ 2.negate() = -12, 321 / 49 r2 ^ 2.invert() = 49 / 12,
321 r2 ^ 2.intValue() = 251 r2 ^ 2.longValue() = 251 r2
^ 2.floatValue() = 251.448975 r2 ^ 2.doubleValue() = 251.448980
Rashmi is a professional Software Developer with hands on over varied tech stack. She has been working on Java, Springboot, Microservices, Typescript, MySQL, Graphql and more. She loves to spread knowledge via her writings. She is keen taking up new things and adopt in her career.
LinkedIn