迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > Java >

Java 中的分数

作者:迹忆客 最近更新:2023/09/28 浏览次数:

在数学上,分数是值的部分或部分。当一个物体以一定的比例被均等地分解时,所形成的值称为分数。分数分为有理数和无理数。

在 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 应始终为真。该方法编写了满足有理数基本条件的逻辑。它分别检查分子和分母的符号并执行运算。它检查分母值;如果它是零,操作会抛出一个异常。它还检查分子和分母值中的最大公约数或 gcdgcd 函数存在于返回 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

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

如何在 Java 中延迟几秒钟的时间

发布时间:2023/12/17 浏览次数:217 分类:Java

本篇文章主要介绍如何在 Java 中制造程序延迟。本教程介绍了如何在 Java 中制造程序延时,并列举了一些示例代码来了解它。

如何在 Java 中把 Hashmap 转换为 JSON 对象

发布时间:2023/12/17 浏览次数:187 分类:Java

它描述了允许我们将哈希图转换为简单的 JSON 对象的方法。本文介绍了在 Java 中把 Hashmap 转换为 JSON 对象的方法。我们将看到关于创建一个 hashmap,然后将其转换为 JSON 对象的详细例子。

如何在 Java 中按值排序 Map

发布时间:2023/12/17 浏览次数:171 分类:Java

本文介绍了如何在 Java 中按值对 Map 进行排序。本教程介绍了如何在 Java 中按值对 Map 进行排序,并列出了一些示例代码来理解它。

如何在 Java 中打印 HashMap

发布时间:2023/12/17 浏览次数:192 分类:Java

本帖介绍了如何在 Java 中打印 HashMap。本教程介绍了如何在 Java 中打印 HashMap 元素,还列举了一些示例代码来理解这个主题。

在 Java 中更新 Hashmap 的值

发布时间:2023/12/17 浏览次数:146 分类:Java

本文介绍了如何在 Java 中更新 HashMap 中的一个值。本文介绍了如何在 Java 中使用 HashMap 类中包含的两个方法-put() 和 replace() 更新 HashMap 中的值。

Java 中的 hashmap 和 map 之间的区别

发布时间:2023/12/17 浏览次数:79 分类:Java

本文介绍了 Java 中的 hashmap 和 map 接口之间的区别。本教程介绍了 Java 中 Map 和 HashMap 之间的主要区别。在 Java 中,Map 是用于以键值对存储数据的接口,

在 Java 中获取用户主目录

发布时间:2023/12/17 浏览次数:218 分类:Java

这篇文章向你展示了如何在 Java 中获取用户主目录。本教程介绍了如何在 Java 中获取用户主目录,并列出了一些示例代码以指导你完成该主题。

Java 中 size 和 length 的区别

发布时间:2023/12/17 浏览次数:179 分类:Java

这篇文章教你如何知道 Java 中大小和长度之间的区别。本教程介绍了 Java 中大小和长度之间的区别。我们还列出了一些示例代码以帮助你理解该主题。

Java 中的互斥锁

发布时间:2023/12/17 浏览次数:111 分类:Java

了解有关 Java 中互斥锁的一切,在计算机科学领域,互斥或互斥被称为并发控制的属性。每台计算机都使用称为线程的最小程序指令序列。有一次,计算机在一个线程上工作。为了更好地理解,

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便