Fraction.java

1
package com.github.dakusui.symfonion.utils;
2
3
4
5
import com.github.dakusui.symfonion.exceptions.FractionFormatException;
6
7
import java.io.Serial;
8
import java.io.Serializable;
9
import java.util.regex.Matcher;
10
import java.util.regex.Pattern;
11
12
import static com.github.dakusui.symfonion.exceptions.ExceptionThrower.throwFractionFormatException;
13
import static com.github.dakusui.valid8j.Requires.requireArgument;
14
import static com.github.dakusui.valid8j_pcond.forms.Predicates.isEqualTo;
15
import static com.github.dakusui.valid8j_pcond.forms.Predicates.not;
16
17
18
/**
19
 * A class to implement simple Fraction functions
20
 * there is basically a constructor (which reduces)
21
 */
22
public record Fraction(int numerator, int denominator) implements Cloneable, Serializable {
23
  public static final Pattern fractionPattern = Pattern.compile("([0-9]+)/([1-9][0-9]*)");
24
  @Serial
25
  private static final long serialVersionUID = 9185757132113L;
26
27
  /* some useful constant fractions */
28
  public static final Fraction zero = new Fraction(0, 1);
29
  public static final Fraction one = new Fraction(1, 1);
30
31
  public Fraction(int numerator, int denominator) {
32
    requireArgument(denominator, not(isEqualTo(0)));
33
    int n = numerator;
34
    int d = denominator;
35
    int gcd;
36
37
    while (true) {
38
      gcd = this.gcd(n, d);
39
      if (gcd == 1)
40
        break;
41
      n /= gcd;
42
      d /= gcd;
43
    }
44
    this.numerator = n;
45
    this.denominator = d;
46
  }
47
48
  public static Fraction parseFraction(String str) throws FractionFormatException {
49 1 1. parseFraction : negated conditional → KILLED
    if (str == null) {
50
      return null;
51
    }
52
    Matcher m = fractionPattern.matcher(str);
53 1 1. parseFraction : negated conditional → KILLED
    if (!m.matches()) {
54
      throw throwFractionFormatException(str);
55
    }
56 1 1. parseFraction : replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::parseFraction → SURVIVED
    return new Fraction(
57
        Integer.parseInt(m.group(1)),
58
        Integer.parseInt(m.group(2))
59
    );
60
  }
61
62
  @Override
63
  public Fraction clone() {
64
    Fraction ret;
65
    try {
66
      ret = (Fraction) super.clone();
67
    } catch (CloneNotSupportedException e) {
68
      throw new AssertionError(e);
69
    }
70 1 1. clone : replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::clone → KILLED
    return ret;
71
  }
72
73
  private int gcd(int a, int b) {
74
    int t;
75
76 1 1. gcd : negated conditional → KILLED
    while (b != 0) {
77
      t = a;
78
      a = b;
79 1 1. gcd : Replaced integer modulus with multiplication → TIMED_OUT
      b = t % a;
80
    }
81 1 1. gcd : replaced int return with 0 for com/github/dakusui/symfonion/utils/Fraction::gcd → KILLED
    return (a);
82
  }
83
84
  public double doubleValue() {
85 3 1. doubleValue : replaced double return with 0.0d for com/github/dakusui/symfonion/utils/Fraction::doubleValue → KILLED
2. doubleValue : Replaced double multiplication with division → KILLED
3. doubleValue : Replaced double division with multiplication → KILLED
    return (1.0 * this.numerator() / this.denominator());
86
  }
87
88
  public int wholePortion() {
89 1 1. wholePortion : replaced int return with 0 for com/github/dakusui/symfonion/utils/Fraction::wholePortion → KILLED
    return (int) this.doubleValue();
90
  }
91
92
  public Fraction fractionPortion() {
93
    Fraction f = new Fraction(this.wholePortion(), 1);
94 1 1. fractionPortion : replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::fractionPortion → KILLED
    return subtract(this, f);
95
  }
96
97
  @Override
98
  public boolean equals(Object anotherObject) {
99 1 1. equals : negated conditional → KILLED
    if (!(anotherObject instanceof Fraction another))
100 1 1. equals : replaced boolean return with true for com/github/dakusui/symfonion/utils/Fraction::equals → KILLED
      return false;
101 3 1. equals : negated conditional → KILLED
2. equals : replaced boolean return with true for com/github/dakusui/symfonion/utils/Fraction::equals → KILLED
3. equals : negated conditional → KILLED
    return this.denominator == another.denominator && this.numerator == another.numerator;
102
  }
103
104
  @Override
105
  public String toString() {
106 1 1. toString : replaced return value with "" for com/github/dakusui/symfonion/utils/Fraction::toString → KILLED
    return (this.numerator() + "/" + this.denominator());
107
  }
108
109
  public static Fraction add(Fraction f1, Fraction f2) {
110
    int n,
111
        d;
112
113 3 1. add : Replaced integer multiplication with division → KILLED
2. add : Replaced integer addition with subtraction → KILLED
3. add : Replaced integer multiplication with division → KILLED
    n = f1.numerator * f2.denominator + f2.numerator * f1.denominator;
114 1 1. add : Replaced integer multiplication with division → KILLED
    d = f1.denominator * f2.denominator;
115 1 1. add : replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::add → KILLED
    return new Fraction(n, d);
116
  }
117
118
  public static Fraction subtract(Fraction f1, Fraction f2) {
119
    int n,
120
        d;
121
122 3 1. subtract : Replaced integer multiplication with division → KILLED
2. subtract : Replaced integer subtraction with addition → KILLED
3. subtract : Replaced integer multiplication with division → KILLED
    n = f1.numerator * f2.denominator - f2.numerator * f1.denominator;
123 1 1. subtract : Replaced integer multiplication with division → KILLED
    d = f1.denominator * f2.denominator;
124 1 1. subtract : replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::subtract → KILLED
    return new Fraction(n, d);
125
  }
126
127
128
  /**
129
   * Multiplies two fractions.
130
   *
131
   * @param f1 A fraction.
132
   * @param f2 Another fraction.
133
   * @return A multiplied result.
134
   */
135
  public static Fraction multi(Fraction f1, Fraction f2) {
136 3 1. multi : Replaced integer multiplication with division → KILLED
2. multi : Replaced integer multiplication with division → KILLED
3. multi : replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::multi → KILLED
    return new Fraction(f1.numerator * f2.numerator, f1.denominator * f2.denominator);
137
  }
138
139
  public static Fraction div(Fraction f1, Fraction f2) {
140 3 1. div : Replaced integer multiplication with division → SURVIVED
2. div : Replaced integer multiplication with division → KILLED
3. div : replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::div → KILLED
    return new Fraction(f1.numerator * f2.denominator, f1.denominator * f2.numerator);
141
  }
142
143
  public static int compare(Fraction f1, Fraction f2) {
144
    Fraction sub = subtract(f1, f2);
145 2 1. compare : Replaced integer multiplication with division → KILLED
2. compare : replaced int return with 0 for com/github/dakusui/symfonion/utils/Fraction::compare → KILLED
    return sub.numerator * sub.denominator;
146
  }
147
148
  public static Fraction max(Fraction f1, Fraction f2) {
149 3 1. max : changed conditional boundary → SURVIVED
2. max : negated conditional → KILLED
3. max : Replaced double subtraction with addition → KILLED
    if (f1.doubleValue() - f2.doubleValue() >= 0)
150 1 1. max : replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::max → KILLED
      return f1;
151
    else
152 1 1. max : replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::max → KILLED
      return f2;
153
  }
154
155
  public static Fraction min(Fraction f1, Fraction f2) {
156 3 1. min : changed conditional boundary → SURVIVED
2. min : Replaced double subtraction with addition → KILLED
3. min : negated conditional → KILLED
    if (f1.doubleValue() - f2.doubleValue() <= 0)
157 1 1. min : replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::min → KILLED
      return f1;
158
    else
159 1 1. min : replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::min → KILLED
      return f2;
160
  }
161
162
}

Mutations

49

1.1
Location : parseFraction
Killed by : com.github.dakusui.symfonion.tests.InvalidDataErrorTest.illegalFraction(com.github.dakusui.symfonion.tests.InvalidDataErrorTest)
negated conditional → KILLED

53

1.1
Location : parseFraction
Killed by : com.github.dakusui.symfonion.tests.InvalidJsonErrorTest.missingSection_pattern(com.github.dakusui.symfonion.tests.InvalidJsonErrorTest)
negated conditional → KILLED

56

1.1
Location : parseFraction
Killed by : none
replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::parseFraction → SURVIVED

70

1.1
Location : clone
Killed by : com.github.dakusui.symfonion.tests.song.GrooveTest.test_B01(com.github.dakusui.symfonion.tests.song.GrooveTest)
replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::clone → KILLED

76

1.1
Location : gcd
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_equals_3(com.github.dakusui.symfonion.tests.core.FractionTest)
negated conditional → KILLED

79

1.1
Location : gcd
Killed by : none
Replaced integer modulus with multiplication → TIMED_OUT

81

1.1
Location : gcd
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_equals_3(com.github.dakusui.symfonion.tests.core.FractionTest)
replaced int return with 0 for com/github/dakusui/symfonion/utils/Fraction::gcd → KILLED

85

1.1
Location : doubleValue
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_subtract_02(com.github.dakusui.symfonion.tests.core.FractionTest)
replaced double return with 0.0d for com/github/dakusui/symfonion/utils/Fraction::doubleValue → KILLED

2.2
Location : doubleValue
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_max_1(com.github.dakusui.symfonion.tests.core.FractionTest)
Replaced double multiplication with division → KILLED

3.3
Location : doubleValue
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_subtract_02(com.github.dakusui.symfonion.tests.core.FractionTest)
Replaced double division with multiplication → KILLED

89

1.1
Location : wholePortion
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_fractionPortion_91(com.github.dakusui.symfonion.tests.core.FractionTest)
replaced int return with 0 for com/github/dakusui/symfonion/utils/Fraction::wholePortion → KILLED

94

1.1
Location : fractionPortion
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_fractionPortion_91(com.github.dakusui.symfonion.tests.core.FractionTest)
replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::fractionPortion → KILLED

99

1.1
Location : equals
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_equals_2(com.github.dakusui.symfonion.tests.core.FractionTest)
negated conditional → KILLED

100

1.1
Location : equals
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_equals_4(com.github.dakusui.symfonion.tests.core.FractionTest)
replaced boolean return with true for com/github/dakusui/symfonion/utils/Fraction::equals → KILLED

101

1.1
Location : equals
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_equals_2(com.github.dakusui.symfonion.tests.core.FractionTest)
negated conditional → KILLED

2.2
Location : equals
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_equals_3(com.github.dakusui.symfonion.tests.core.FractionTest)
replaced boolean return with true for com/github/dakusui/symfonion/utils/Fraction::equals → KILLED

3.3
Location : equals
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_equals_3(com.github.dakusui.symfonion.tests.core.FractionTest)
negated conditional → KILLED

106

1.1
Location : toString
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_toString(com.github.dakusui.symfonion.tests.core.FractionTest)
replaced return value with "" for com/github/dakusui/symfonion/utils/Fraction::toString → KILLED

113

1.1
Location : add
Killed by : com.github.dakusui.symfonion.tests.song.GrooveTest.test_A04(com.github.dakusui.symfonion.tests.song.GrooveTest)
Replaced integer multiplication with division → KILLED

2.2
Location : add
Killed by : com.github.dakusui.symfonion.tests.song.GrooveTest.test_A04(com.github.dakusui.symfonion.tests.song.GrooveTest)
Replaced integer addition with subtraction → KILLED

3.3
Location : add
Killed by : com.github.dakusui.symfonion.tests.song.GrooveTest.test_A04(com.github.dakusui.symfonion.tests.song.GrooveTest)
Replaced integer multiplication with division → KILLED

114

1.1
Location : add
Killed by : com.github.dakusui.symfonion.tests.song.GrooveTest.test_A04(com.github.dakusui.symfonion.tests.song.GrooveTest)
Replaced integer multiplication with division → KILLED

115

1.1
Location : add
Killed by : com.github.dakusui.symfonion.tests.song.GrooveTest.test_A04(com.github.dakusui.symfonion.tests.song.GrooveTest)
replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::add → KILLED

122

1.1
Location : subtract
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_compare_03(com.github.dakusui.symfonion.tests.core.FractionTest)
Replaced integer multiplication with division → KILLED

2.2
Location : subtract
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_compare01(com.github.dakusui.symfonion.tests.core.FractionTest)
Replaced integer subtraction with addition → KILLED

3.3
Location : subtract
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_compare_02(com.github.dakusui.symfonion.tests.core.FractionTest)
Replaced integer multiplication with division → KILLED

123

1.1
Location : subtract
Killed by : com.github.dakusui.symfonion.tests.song.GrooveTest.test_B02(com.github.dakusui.symfonion.tests.song.GrooveTest)
Replaced integer multiplication with division → KILLED

124

1.1
Location : subtract
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_compare01(com.github.dakusui.symfonion.tests.core.FractionTest)
replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::subtract → KILLED

136

1.1
Location : multi
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_multiply_01(com.github.dakusui.symfonion.tests.core.FractionTest)
Replaced integer multiplication with division → KILLED

2.2
Location : multi
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_multiply_01(com.github.dakusui.symfonion.tests.core.FractionTest)
Replaced integer multiplication with division → KILLED

3.3
Location : multi
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_multiply_01(com.github.dakusui.symfonion.tests.core.FractionTest)
replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::multi → KILLED

140

1.1
Location : div
Killed by : com.github.dakusui.symfonion.tests.song.GrooveTest.test_A02(com.github.dakusui.symfonion.tests.song.GrooveTest)
Replaced integer multiplication with division → KILLED

2.2
Location : div
Killed by : com.github.dakusui.symfonion.tests.song.GrooveTest.test_A02(com.github.dakusui.symfonion.tests.song.GrooveTest)
replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::div → KILLED

3.3
Location : div
Killed by : none
Replaced integer multiplication with division → SURVIVED

145

1.1
Location : compare
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_compare_02(com.github.dakusui.symfonion.tests.core.FractionTest)
Replaced integer multiplication with division → KILLED

2.2
Location : compare
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_compare_02(com.github.dakusui.symfonion.tests.core.FractionTest)
replaced int return with 0 for com/github/dakusui/symfonion/utils/Fraction::compare → KILLED

149

1.1
Location : max
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_max_1(com.github.dakusui.symfonion.tests.core.FractionTest)
negated conditional → KILLED

2.2
Location : max
Killed by : none
changed conditional boundary → SURVIVED

3.3
Location : max
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_max_1(com.github.dakusui.symfonion.tests.core.FractionTest)
Replaced double subtraction with addition → KILLED

150

1.1
Location : max
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_max_2(com.github.dakusui.symfonion.tests.core.FractionTest)
replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::max → KILLED

152

1.1
Location : max
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_max_1(com.github.dakusui.symfonion.tests.core.FractionTest)
replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::max → KILLED

156

1.1
Location : min
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_min_1(com.github.dakusui.symfonion.tests.core.FractionTest)
Replaced double subtraction with addition → KILLED

2.2
Location : min
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_min_1(com.github.dakusui.symfonion.tests.core.FractionTest)
negated conditional → KILLED

3.3
Location : min
Killed by : none
changed conditional boundary → SURVIVED

157

1.1
Location : min
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_min_1(com.github.dakusui.symfonion.tests.core.FractionTest)
replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::min → KILLED

159

1.1
Location : min
Killed by : com.github.dakusui.symfonion.tests.core.FractionTest.test_min_2(com.github.dakusui.symfonion.tests.core.FractionTest)
replaced return value with null for com/github/dakusui/symfonion/utils/Fraction::min → KILLED

Active mutators

Tests examined


Report generated by PIT 1.15.3