В этом проекте я должен создать класс Polynomial. Вот что у меня есть для файла Polynomial.cpp:
#include <iostream>
#include "Polynomial.h"
#include <stdexcept>
#include <iomanip>
#include <cmath>
#include <string>
using namespace std;
Polynomial::Polynomial(double c[], int size){
set(c,size);
}
Polynomial::Polynomial(const Polynomial &poly){
size = poly.size;
c = new double[size];
for(int i=0; i<size; i++){
c[i] = poly.c[i];
}
}
Polynomial::~Polynomial(){
delete [] c;
}
void Polynomial::set(double ca[], int s){
if (s < 1){
throw std::invalid_argument("Size must be larger or equal to 1.");
}
else{
size = s;
c = new double[size];
for(int i=0; i<size; i++){
c[i] = ca[i];
}
}
}
double* Polynomial::getPointer() const{
return c;
}
int Polynomial::getSize() const{
return size;
}
bool Polynomial::operator ==(const Polynomial& poly) const{
if (size != poly.size){
return false;
}
int i = 0;
int count = 0;
while ( i < size ) {
if ( c[i] == poly.c[i] ) {
count++;
}
i++;
}
if ( count != size) {
return false;
}
return true;
}
Polynomial Polynomial::operator +(const Polynomial& poly) const{
int d = fabs(size - poly.size); //absolute value of size difference
int bigger = size; //the size of the bigger polynomial
int smaller = poly.size; //the size of the smaller polynomial
if ( poly.size > size) {
bigger = poly.size;
smaller = size;
}
double r[bigger];
double s[bigger]; //new coef array for the smaller polynomial with zeros coefs added
if ( d != 0 ) {
if (smaller = poly.size){
for(int i=0; i < smaller; i++){
s[i] = poly.c[i];
}
for(int i=smaller; i < bigger; i++){
s[i] = 0;
}
for(int i=0; i < bigger; i++){
r[i] = c[i] + s[i];
}
}
else{
for(int i=0; i < smaller; i++){
s[i] = c[i];
}
for(int i=smaller; i < bigger; i++){
s[i] = 0;
}
for(int i=0; i < bigger; i++){
r[i] = poly.c[i] + s[i];
}
}
}
else {
for ( int i = 0; i < bigger; i++) {
r[i] = c[i] + poly.c[i];
}
}
return Polynomial(r,bigger);
}
ostream& operator<<(ostream &lhs, const Polynomial &poly){
string plus = "+";
bool valid = false; //check if the first term of the polynomial to be printed is valid or not, valid is true when term is non-zero
if (poly.getPointer()[poly.getSize()-1] < 0){
if (poly.getPointer()[poly.getSize()-1] != 0){
lhs << setprecision(1) << fixed << poly.getPointer()[poly.getSize()-1] << "x^" << poly.getSize()-1 << " ";
}
for(int i=poly.getSize()-2; i >= 0; i--){
if (poly.getPointer()[i] != 0 && i != 1 && i != 0){
if (poly.getPointer()[i] > 0){
lhs << setprecision(1) << fixed << plus << poly.getPointer()[i] << "x^" << i << " ";
}
else{
lhs << setprecision(1) << fixed << poly.getPointer()[i] << "x^" << i << " ";
}
}
else if (poly.getPointer()[i] != 0 && i == 1){
if (poly.getPointer()[i] > 0){
lhs << setprecision(1) << fixed << plus << poly.getPointer()[i] << "x" << " ";
}
else{
lhs << setprecision(1) << fixed << poly.getPointer()[i] << "x" << " ";
}
}
else if (poly.getPointer()[i] != 0 && i == 0){
if (poly.getPointer()[i] > 0){
lhs << setprecision(1) << fixed << plus << poly.getPointer()[i];
}
else{
lhs << setprecision(1) << fixed << poly.getPointer()[i];
}
}
}
}
else{
if (poly.getPointer()[poly.getSize()-1] != 0){
lhs << setprecision(1) << fixed << noshowpos << poly.getPointer()[poly.getSize()-1] << "x^" << poly.getSize()-1 << " ";
valid = true;
}
for(int i=poly.getSize()-2; i >= 0; i--){
if (poly.getPointer()[i] != 0 && i != 1 && i != 0){
if (poly.getPointer()[i] > 0 && valid == true){
lhs << setprecision(1) << fixed << plus << poly.getPointer()[i] << "x^" << i << " ";
}
else{
lhs << setprecision(1) << fixed << poly.getPointer()[i] << "x^" << i << " ";
valid = true;
}
}
else if (poly.getPointer()[i] != 0 && i == 1){
if (poly.getPointer()[i] > 0 && valid == true){
lhs << setprecision(1) << fixed << plus << poly.getPointer()[i] << "x" << " ";
}
else{
lhs << setprecision(1) << fixed << poly.getPointer()[i] << "x" << " ";
valid = true;
}
}
else if (poly.getPointer()[i] != 0 && i == 0){
if (poly.getPointer()[i] > 0 && valid == true){
lhs << setprecision(1) << fixed << plus << poly.getPointer()[i];
}
else{
lhs << setprecision(1) << fixed << poly.getPointer()[i];
valid = true;
}
}
}
}
return lhs;
}
Вот моя тестовая программа:
#include <iostream>
#include "Polynomial.h"
#include <iomanip>
using namespace std;
int main() {
double c[] = {0,-5,3};
double d[] = {3,0,-5,0};
Polynomial p1(c,3);
Polynomial p2(d,4);
cout << "Polynomial p1 is: " << p1 << endl;
cout << "Degree of polynomial p1 is: " << noshowpos << p1.getDegree() << endl;
cout << "Polynomial p2 is: " << p2 << endl;
Polynomial p3(p1);
cout << "Polynomial p3 now is equal to p1 after copy constructor: " << p3 << endl;
bool same = p1 == p3;
cout << "Is p1 equal to p3? " << noshowpos << same << endl;
Polynomial p4 = p1 + p2;
cout << "Polynomial p4 is the sum of p1 and p2: " << p4 << endl;
Итак, проблема, с которой я столкнулся, связана с этим выражением if:
if (poly.getPointer()[poly.getSize()-1] != 0){
lhs << setprecision(1) << fixed << poly.getPointer()[poly.getSize()-1] << "x^" << poly.getSize()-1 << " ";
}
Когда я выполняю оператор + для p4 = p1 + p2, полиномиальный массив double для p4 равен [3, -5, -2, 0]. Таким образом, последнее значение p4 [size - 1] этого массива равно 0. Как вы можете видеть выше в операторе if, когда я получаю значение poly.getPointer () [poly.getSize () - 1], оно равно 0; однако, когда я сравниваю его с нулем в операторе if, он все равно выполняется, даже если оператор if ложен (0 не равно 0, поэтому этот оператор if следует пропустить). Я пробовал запускать его как в среде IDE, так и на движке Linux; однако результат все тот же. Я не уверен, связано ли это с этим конструктором, который вызывает метод set:
Polynomial::Polynomial(double c[], int size){
set(c,size);
}
void Polynomial::set(double ca[], int s){
if (s < 1){
throw std::invalid_argument("Size must be larger or equal to 1.");
}
else{
size = s;
c = new double[size];
for(int i=0; i<size; i++){
c[i] = ca[i];
}
}
}
Пожалуйста помоги. Спасибо.
@Someprogrammerdude Если вы не можете сравнивать значения, вы также можете выполнять вычисления.
@curiousguy Сравнения для точное равенство Я сказал. Сравнения в целом (например, больше / меньше или равенство с эпсилоном) просто прекрасны. Что касается вычислений, чем больше их вы выполняете со значениями с плавающей запятой, тем более неточными они становятся.
@Someprogrammerdude Если вы не можете сравнить на равенство, компилятор сломан. Так что сравнивать нельзя вообще.
@curiousguy Хорошо, я не говорю, что нельзя сравнивать использование == со значениями с плавающей запятой, или что компилятор не разрешает это или что-то в этом роде. Я говорю, что это бессмысленно, поскольку значения с плавающей запятой имеют тенденцию терять точность после нескольких вычислений из-за ошибок округления, и то, что вы можете подумать, 12.345 может не быть точно12.345. Это делает сравнения с использованием ==бессмысленно, поскольку казаться редко работает так, как думают новички.
@Someprogrammerdude Сравнение на равенство должен делает то, что обычно делает, то есть проверяет, является ли одно значение копией другого, или два значения были получены одними и теми же вычислениями на основе одних и тех же значений, или два значения, используемые в одном и том же "обычном" вычислении. даст тот же результат.





Вы не можете сравнивать значения с плавающей запятой для точного равенства на компьютерах. См., Например, Математика с плавающей запятой не работает? для некоторых деталей