Brüche in Java
Mathematisch sind Brüche die Teile oder Abschnitte von Werten. Wenn ein Objekt in bestimmten Proportionen gleichmäßig gebrochen wird, wird der gebildete Wert Bruch genannt. Brüche werden in rationale und irrationale Zahlen eingeteilt.
In der Programmiersprache Java gibt es das Privileg, verschiedene Operationen über Brüche wie mathematische Prozeduren auszuführen. Man kann die Bruchzahlen addieren, subtrahieren, multiplizieren und dividieren.
Unten ist der Codeblock, der die rationalen Zahlenoperationen in der benutzerdefinierten Klasse demonstriert.
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);
}
}
Im obigen Programm beginnt die Ausführung mit der Methode main
. Zunächst wird eine rationale Zahl mit der in der Klasse definierten statischen Funktion valueOf()
initialisiert. Es nimmt einen Zeichenkettenwert an und führt Manipulationen an der EingabeZeichenkette durch.
Es gibt eine RationalNumber
des benutzerdefinierten Typs zurück. Die Funktion sucht zuerst nach einem Eingabe-String mit den richtigen Validierungen und Mustern. Der Eingabe-String wird in Exponenten, Dezimalzahlen und den ganzen Teil getrennt. Diese einzelnen gebrochenen Werte verbinden sich zu einer rationalen Zahl.
Eine andere Möglichkeit, eine rationale Zahl zu erzeugen, ist die Verwendung einer statischen Factory-Funktion instanceOf()
. Die Methode ruft intern die Funktion canonical
auf, die einen privaten Konstruktor der Klasse aufruft. Der Konstruktor trennt und legt die Werte von Zähler und Nenner für eine bestimmte Instanz fest. Mit kanonischer Form ist einfach die Standarddarstellungsform der rationalen Zahl gemeint.
Im gegebenen Fall ist p/q
die Standard- oder kanonische Form, wobei q!=0
immer wahr sein sollte. Die Methode hat die Logik geschrieben, um die Grundbedingungen einer rationalen Zahl zu erfüllen. Es prüft das Vorzeichen von Zähler und Nenner getrennt und führt Operationen durch. Es prüft auf Nennerwerte; wenn es null
ist, wirft die Operation eine Exception
. Es prüft auch auf den größten gemeinsamen Teiler oder gcd
in den Zähler- und Nennerwerten. Die Funktion gcd
ist in der Klasse BigInteger
vorhanden, die einen BigInteger
-Wert zurückgibt.
Im weiteren Verlauf wird die Methode convert
aufgerufen, die die erste erzeugte Instanz der rationalen Zahl übergibt. Auch diese Methode ruft über die übergebene Instanz rationale Zahl sieben verschiedene Funktionen auf.
Im Folgenden werden Sie jede dieser Methoden besser verstehen:
- Drucken Sie die rationale Zahl im Druckstrom. Im Allgemeinen wird bei jeder Ausgabe einer Instanz die Standardmethode
toString
aufgerufen. Die Methode gibt den Namen der Klasse gefolgt von der hexadezimalen Darstellung des Speicherorts aus. Aber hier wird die Funktion überschrieben, um eine andere Implementierung zu erhalten, die die Zahl in der Formp/q
darstellt. - Die Funktion
negate
negiert intern die rationale Zahl, indem sie die Methodenegate
der KlasseBigInteger
aufruft. Es wird ein Minuszeichen vor der rationalen Zahl hinzugefügt. - Die Invert-Funktion ruft intern die
canonical
Methode mit einem einzigen Unterschied auf. Es übergibt intern den drittencheckGcd
-Parameter als false. Wenn der Eingabewert Boolean true ist, vereinfacht die Methodenlogik die rationale Zahl, indem sie den Bruch durch seinen größten gemeinsamen Teiler dividiert. Aber in diesem Fall besteht die Notwendigkeit, ohne Vereinfachung zu invertieren. - Die Funktion
intValue
prüft zunächst, ob die Instanz einInteger
-Wert ist.Integers
sind Zahlen, die positiv, negativ oder null sein können, aber keine Brüche sein können. Intern ruft es also die Methodedivide
über Zähler und Nenner auf. Die Methode wird in der KlasseBigInteger
angegeben und gibt einenBigInteger
-Wert zurück. Es wirft auchArithmeticException
, wenn der Nenner einenNull
-Wert findet. Der zurückgegebene Wert wird mit der FunktionintValue
in einenint
-Wert umgewandelt. - Die Funktion
longValue
ruft intern die Divide-Funktion auf und analysiert die Ausgabe vonBigInteger
auf den Datentyplong
. - Die Funktion
floatValue
liefert den Gleitkommawert der rationalen Zahl. Und so wie die FunktiondoubleValue()
, die die Ausgabe in den DatentypDouble
umwandelt.
Der gesamte Prozess wird von einer anfänglichen rationalen Zahlinstanz aufgerufen, die die r1
-Instanz ist. Eine ähnliche Sequenz wird noch einmal wiederholt und für die rationale Instanz r2
ausgegeben.
Mathematische Operationen für Brüche in Java
Addieren, subtrahieren, dividieren, multiplizieren und arithmetische Operationen benötigen nun zwei Operanden zur Auswertung. Lassen Sie uns die Methoden im Folgenden im Detail besprechen:
- Die Funktion
add
prüft zuerst, ob die Zählerwerte positiv, negativ oder null sind. Falls nicht Null, prüft es, ob die Nenner der beiden rationalen Zahlen gleich sind. Wenn das gleiche gefunden wird, addiert es den Zählerwert und gibt die gebildete rationale Zahl zurück. Andernfalls, wenn es nicht ähnlich gefunden wird, definiert es die Logik für die Addition rationaler Zahlen. - Die Methode
subtract
ruft intern die Methodeadd
auf, nachdem die zweite übergebene Instanz der rationalen Zahl negiert wurde. - Die Methode
multiply
hat intern eine recht komplexe Logik. Es prüft, ob der Zähler Null einer der rationalen Zahlen ist, und gibt die Ausgabe als Nullwert zurück. Falls nicht Null, überprüft es den Zähler mit dem Nenner einer der beiden Mengen. Das heißt, der Zählerr1
wird mit dem Nennerr2
überprüft und umgekehrt. Wenn keine Bedingung zutrifft, wird der Zähler vonr1
mit dem Instanzzählerr2
multipliziert, und die Nenner von beiden werden multipliziert. Schließlich ruft es die Funktionmultiply
der KlasseBigInteger
auf, um die Multiplikation durchzuführen. - Die Funktion
divide
invertiert die übergebene Instanz und ruft intern die Funktionmultiply
mit der ersten Instanz auf. - Zuletzt ist die Funktion
pow
, die die zweite Potenz der Instanzr2
auswertet. Die Implementierung vonpow
wird in der KlasseBigInteger
definiert, die den Exponenten zur Auswertung verwendet. Die Methode löst die AusnahmeArithmeticException
aus, wenn der Exponent einen negativen Wert hat.
Unten ist die Ausgabe des oben angegebenen komplexen Codes:
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