I am making a program which inputs fractions and puts them in order. I used struct to define a fraction type. I think I am making a type that initializing 2 variables(the numerator and the denominator of the fraction) and initializing the double type variable called value to a / b in this code:
struct fraction {
int a; // numerator
int b; // denominator
double value = a / b; // floating point value of fraction
bool operator > (const fraction &a) {
fraction ans;
return ans.value > a.value;
}
bool operator < (const fraction &a) {
fraction ans;
return ans.value < a.value;
}
};
int main() {
//---------logging-------
fraction ratio = {1,2};
cout << ratio.value;
//-----------------------
// outputs 0
// other things down here that is not included
}
but apparently, that is not the case because I also need to initialize value. I figured out why, but the problem is, how can I make the variable without initializing it at the creation of the fraction?
CodePudding user response:
I think there are two solutions, either you initialize a and b with 0, or you compute a/b each time you need it.
...or you could write an exception like:
int a;
int b;
double val;
try() { val = a/b; }
catch(...){ val = 0; }
I don't think that's good tho because it's always gong to catch.
CodePudding user response:
How can I make the variable without initializing it at the creation of the fraction?
One could just write a member function double value()
calculating and returning the floating-point value of the fraction, but first there are some issues in the posted code that need to be addressed (and may actually solve OP's problem).
The only in-class member variable initialization shown isn't correct.
double value = a / b; // floating point value of fraction
Beeing both
a
andb
variables of typeint
,a / b
is an integer division, yielding anint
result that is only after assigned to adouble
variable. In OP's example,int(1)/int(2) == int(0)
.To produce the expected value, we need to explicitly convert at least one of the terms into a
double
:double value = static_cast<double>(a) / b;
Both the comparison operators are wrong.
bool operator > (const fraction &a) { fraction ans; // This is a LOCAL, UNINITIALIZED varible. return ans.value > a.value; // The result is meaningless. }
The following snippet shows a possible implementation where value
is calculated and not stored (which isn't necessary a good idea).
#include <iostream>
#include <numeric>
class fraction
{
int numerator_{};
int denominator_{1};
public:
fraction() = default;
fraction(int num, int den)
: numerator_{num}, denominator_{den}
{
if (auto divisor = std::gcd(num, den); divisor != 1)
{
numerator_ /= divisor;
denominator_ /= divisor;
}
}
bool operator > (fraction const& a) const noexcept {
return value() > a.value();
}
bool operator < (fraction const& a) const noexcept {
return value() < a.value();
}
auto numerator() const noexcept {
return numerator_;
}
auto denominator() const noexcept {
return denominator_;
}
double value() const noexcept {
return static_cast<double>(numerator_) / denominator_;
}
};