Java 中的分数
在数学上,分数是值的部分或部分。当一个物体以一定的比例被均等地分解时,所形成的值称为分数。分数分为有理数和无理数。
在 Java 编程语言中,有一种特权可以对分数执行各种运算,例如数学过程。可以对小数进行加、减、乘、除运算。
下面是演示用户定义类中的有理数操作的代码块。
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);
}
}
在上面的程序中,执行从 main
方法开始。首先,使用类中定义的静态 valueOf()
函数初始化一个有理数。它接受一个字符串值并对输入字符串执行操作。
它返回用户定义类型的 RationalNumber
。该函数首先检查具有正确验证和模式的输入字符串。输入字符串被分成指数、小数和整个部分。这些单独的破碎值组合形成一个有理数。
创建有理数的另一种方法是使用 instanceOf()
静态工厂函数。该方法在内部调用 canonical
函数,该函数调用类的私有构造函数。构造函数分离并设置特定实例的分子和分母的值。规范形式,它只是指有理数的标准表示形式。
在给定的情况下,p/q
是标准或规范形式,其中 q!=0
应始终为真。该方法编写了满足有理数基本条件的逻辑。它分别检查分子和分母的符号并执行运算。它检查分母值;如果它是零,操作会抛出一个异常。它还检查分子和分母值中的最大公约数或 gcd
。gcd
函数存在于返回 BigInteger
值的 BigInteger
类中。
继续前进,调用 convert
方法,传递创建的第一个有理数实例。此方法还在传递的有理数实例上调用七个不同的函数。
下面,你将更好地理解这些方法:
-
在打印流中打印有理数。通常,每当打印实例时,都会调用默认的
toString
方法。该方法打印类的名称,后跟内存位置的十六进制表示。但在这里,该函数被覆盖以提供另一个表示p/q
形式的数字的实现。 -
negate
函数将通过调用BigInteger
类的negate
方法在内部否定有理数。它将在有理数之前添加一个减号。 -
invert 函数在内部调用
canonical
方法,但只有一个区别。它在内部将第三个checkGcd
参数作为 false 传递。当输入值为布尔真时,方法逻辑通过将分数除以其最大公约数来简化有理数。但在这种情况下,需要的是不简化的反转。 -
intValue
函数首先检查实例是否为Integer
值。Integers
是可以是正数、负数或零但不能是分数的数字。因此,它在内部对分子和分母调用divide
方法。该方法在BigInteger
类中给出并返回一个BigInteger
值。当分母为零值时,它也会抛出ArithmeticException
。使用intValue
函数将返回值转换为int
值。 -
longValue
函数在内部调用除法函数 snd 将BigInteger
输出解析为long
数据类型。 -
floatValue
函数提供有理数的浮点值。doubleValue()
函数也是如此,它以Double
数据类型对输出进行类型转换。
整个过程调用一个初始有理数实例,即 r1
实例。类似的序列再次重复并为有理实例 r2
打印出来。
Java 中分数的数学运算
现在加、减、除、乘和幂算术运算需要两个操作数进行计算。因此,让我们在下面详细讨论这些方法:
下面是上面给出的复杂代码的输出:
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
相关文章
在 Java 中简化或减少分数
发布时间:2023/09/28 浏览次数:186 分类:Java
-
在数学中,分数是表示为商的数字。它以 a/b 形式表示,其中 a 是被除数(分子),b 是除数(分母)。在数学中,分数代表整体的一部分或一部分。它有分子和分母两部分,其中分子是被除数
在 Java 中计算两点之间的距离
发布时间:2023/09/28 浏览次数:84 分类:Java
-
使用勾股定理,我们可以在 Java 中找到两点之间的距离。本文介绍如何在 Java 中计算两点之间的距离。
在 Java 中计算欧几里得距离
发布时间:2023/09/28 浏览次数:80 分类:Java
-
本文将帮助你使用 Java 计算两点之间的距离。在本文中,我们将研究两点之间距离的计算。在 Java 中计算欧几里得距离
在 Java 中计算数学表达式
发布时间:2023/09/28 浏览次数:146 分类:Java
-
在 Java 编程语言中,你可以使用堆栈计算算术表达式。堆栈是一种适用于先进后出(FILO) 或后进先出(LIFO) 的数据结构机制,我们将使用它来评估算术表达式。
使用 Java FFMPEG 将文件从一种格式转换为另一种格式
发布时间:2023/09/28 浏览次数:97 分类:Java
-
本文演示了如何使用 Java 包装器和 Java 运行时运行 FFMPEG 将文件从一种格式转换为另一种格式。FFMPEG 最适合内容创建者或大多数时间与媒体文件交互的人。今天,我们将探讨如何使用 Java FFMPE
Java 中使用多个变量进行 for 循环
发布时间:2023/09/28 浏览次数:179 分类:Java
-
本文将介绍使用多变量的 for 循环的方法。本文介绍了我们如何在 Java for 循环中使用多个变量。我们可以通过正确遵循 java for 循环的语法来实现。
退出 Java 中的 While 循环
发布时间:2023/09/28 浏览次数:110 分类:Java
-
这篇文章就是要知道如何在 Java 中退出 while 循环。本文介绍了如何退出 Java 中的 while 循环并通过一些示例代码对其进行处理,以帮助你进一步理解该主题。
打破 Java 中的嵌套循环
发布时间:2023/09/28 浏览次数:200 分类:Java
-
这篇文章讨论了如何在 Java 中打破嵌套循环的方法。本文介绍了如何在 Java 中打破嵌套循环的方法。我们包含了一些示例程序,你可以将其作为指南。
在 Java 中跳出 for 循环
发布时间:2023/09/28 浏览次数:112 分类:Java
-
本文将教我们如何跳出 Java 中的 for 循环。在编程中,某些条件需要中断 for 循环或任何其他与此相关的循环。让我们来看看。