| 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 |
|
| 53 |
1.1 |
|
| 56 |
1.1 |
|
| 70 |
1.1 |
|
| 76 |
1.1 |
|
| 79 |
1.1 |
|
| 81 |
1.1 |
|
| 85 |
1.1 2.2 3.3 |
|
| 89 |
1.1 |
|
| 94 |
1.1 |
|
| 99 |
1.1 |
|
| 100 |
1.1 |
|
| 101 |
1.1 2.2 3.3 |
|
| 106 |
1.1 |
|
| 113 |
1.1 2.2 3.3 |
|
| 114 |
1.1 |
|
| 115 |
1.1 |
|
| 122 |
1.1 2.2 3.3 |
|
| 123 |
1.1 |
|
| 124 |
1.1 |
|
| 136 |
1.1 2.2 3.3 |
|
| 140 |
1.1 2.2 3.3 |
|
| 145 |
1.1 2.2 |
|
| 149 |
1.1 2.2 3.3 |
|
| 150 |
1.1 |
|
| 152 |
1.1 |
|
| 156 |
1.1 2.2 3.3 |
|
| 157 |
1.1 |
|
| 159 |
1.1 |