Just signed up, because my mind is blowing up on this stupid error.
I was calculating elliptic curves in a quick and dirty way with everything in 1 source-file.
Then I thought about cleaning up my code and start to separate the functions and classes in different files.
It's been a long time for me programming in C++ so I guess it is a really stupid beginner mistake.
So I am getting LNK1169-Error and LNK2005-Error and the solutions I found are about including .cpp which I am not doing. I although found out about the extern-keyword, but that seems to be kind of the solution for global variables.
Maybe someone can help me.
EDIT:
Sorry for putting that much code. I just don't know what is relevant for the error and what's not.
The error I am getting are like this:
fatal error LNK1169: one or more multiply defined symbols found. Elliptic 1 C:\Users\Björn\documents\visual studio 2015\Projects\Elliptic 1\Debug\Elliptic 1.exe
error LNK2005 "public: int __thiscall Value::operator==(class Value const &)" (??8Value##QAEHABV0##Z) already defined in Tests.obj
error LNK2005 "public: int __thiscall Value::operator==(int)" (??8Value##QAEHH#Z) already defined in Tests.obj
Here is my code:
Value.hpp
#pragma once
extern int PRIME;
// An own Int-Class to overload operators with modulo
class Value
{
public:
int v;
static friend std::ostream& operator<<(std::ostream& os, const Value& a);
Value()
{
this->v = 0;
}
Value(int a)
{
this->v = a;
}
Value operator+(const Value& other)
{
return Value((this->v + other.v) % PRIME);
}
Value operator+(int a)
{
return Value((this->v + a) % PRIME);
}
Value operator-(const Value& other)
{
Value t = Value((v - other.v) % PRIME);
if (t.v < 0)
{
t = t + PRIME;
return t;
}
return t;
}
Value operator-(int a)
{
Value t = Value((v - a) % PRIME);
if (t.v < 0)
{
t = t + PRIME;
return t;
}
return t;
}
void operator=(const Value other)
{
this->v = other.v;
}
Value operator*(const Value& a);
Value operator*(int a);
Value operator^(int a);
Value operator/(const Value& a);
int operator!=(int b);
int operator!=(const Value& b);
int operator==(int b);
int operator==(const Value& b);
Value operator~();
};
Value Value::operator*(const Value& a)
{
return Value((this->v*a.v) % PRIME);
}
Value Value::operator*(int a)
{
return Value((this->v*a) % PRIME);
}
Value Value::operator^(int b)
{
Value ret(1);
Value mul(this->v);
while (b)
{
if (b & 1)
ret = (ret * mul);
b = (b >> 1);
mul = mul * mul;
}
return ret;
}
Value Value::operator/(const Value& a)
{
if (a.v == 0)
return Value(0);
Value f = (Value)a ^ (PRIME - 2);
return *this * f;
}
int Value::operator!=(int b)
{
if (this->v != b)
return 1;
return 0;
}
int Value::operator!=(const Value& b)
{
if (this->v != b.v)
return 1;
return 0;
}
int Value::operator==(int b)
{
if (this->v == b)
return 1;
return 0;
}
int Value::operator==(const Value& b)
{
if (this->v == b.v)
return 1;
return 0;
}
Value Value::operator~()
{
return *this ^ ((PRIME - 1 + 2) / 4);
}
std::ostream& operator<<(std::ostream& os, const Value& a)
{
return os << a.v;
}
Point.hpp
#pragma once
#include "Value.hpp"
#include <iostream>
class Point
{
public:
Value x;
Value y;
Value z = 0;
static friend std::ostream& operator<<(std::ostream& os, const Point& p);
Point(int a, int b)
{
x.v = a;
y.v = b;
}
Point(int a, int b, int c)
{
x.v = a;
y.v = b;
z.v = c;
}
Point(Value a, Value b)
{
x.v = a.v;
y.v = b.v;
}
Point(Value a, Value b, Value c)
{
x.v = a.v;
y.v = b.v;
z.v = c.v;
}
Point& operator=(const Point& other)
{
x.v = other.x.v;
y.v = other.y.v;
z.v = other.z.v;
return *this;
}
int operator==(Point& other)
{
if (this->x == other.x && this->y == other.y && this->z == other.z)
return 1;
return 0;
}
int operator!=(Point& other)
{
if (this->x != other.x || this->y != other.y || this->z != other.z)
return 1;
return 0;
}
};
std::ostream& operator<<(std::ostream& os, const Point& p)
{
if ((Value)p.z == 0)
return os << "(" << p.x.v << "," << p.y.v << ")";
else
return os << "(" << p.x.v << "," << p.y.v << "," << p.z.v << ")";
}
Helper.hpp
#pragma once
#include "Point.hpp"
#include <vector>
// Forward declaration
int isEC(Value a, Value b);
Value calcEC(int x, Value a, Value b);
int testSqr(Value ySqr);
// Point Addition
Point add(Point p1, Point p2, Value a)
{
// 2D Addition
if (p1.z == 0 && p2.z == 0)
{
// 2 different points
if (p1.x.v != p2.x.v || p1.y.v != p2.y.v)
{
// m = (y2-y1)/(x2-x1)
Value h = p2.y - p1.y;
Value j = p2.x - p1.x;
Value m = h / j;
// x3 = m^2-x1-x2
Value f = m*m;
Value g = f - p1.x;
Value x3 = g - p2.x;
// y3 = m(x1-x3)-y1
Value t = p1.x - x3;
Value l = m * t;
Value y3 = l - p1.y;
if (x3.v < 0)
x3 = x3 + PRIME;
if (y3.v < 0)
y3 = y3 + PRIME;
return Point(x3, y3);
}
// Same points
else
{
// m = (3*x1^2+a)/(2*y1)
Value f = p1.x ^ 2;
Value g = f * 3;
Value h = g + a;
Value j = p1.y * 2;
Value m = h / j;
// x3 = m^2-2*x1
Value t = m*m;
Value x = p1.x * 2;
Value x3 = t - x;
// y3 = m(x1-x3)-y1
Value z = p1.x - x3;
Value i = m * z;
Value y3 = i - p1.y;
if (x3.v < 0)
x3 = x3 + PRIME;
if (y3.v < 0)
y3 = y3 + PRIME;
return Point(x3, y3);
}
}
// 3D Addition - Same points
else if (p1 == p2 && p1.z == 1 && p2.z == 1)
{
Value A = p1.y ^ 2;
Value B = p1.x * A * 4;
Value C = (A ^ 2) * 8;
Value D = (p1.x ^ 2)* 3 + a*(p1.z ^ 4);
//Value x3 = (((3 * (p1.x ^ 2) + a*(p1.z ^ 4)) ^ 2) - 8 * p1.x*(p1.y ^ 2));
Value x3 = (D ^ 2) - B * 2;
//Value y3 = (3 * (p1.x ^ 2) + a*(p1.z ^ 4)*(4 * p1.x*(p1.y ^ 2) - x3) - 8 * (p1.y ^ 4));
Value y3 = D*(B - x3) - C;
Value z3 = p1.y*p1.z * 2;
return Point(x3, y3, z3);
}
// 3D Addition - 2 different points
else if (p1 != p2)
{
Value A = p1.z ^ 2;
Value B = p1.z * A;
Value C = p2.x * A;
Value D = p2.y * B;
Value E = C - p1.x;
Value F = D - p1.y;
Value G = E ^ 2;
Value H = G * E;
Value I = p1.x * G;
Value x3 = (F ^ 2) - (H + (I * 2));
Value y3 = F*(I - x3) - p1.y*H;
Value z3 = p1.z * E;
return Point(x3, y3, z3);
}
return Point(0, 0, 0);
}
// Find all points and print them
std::vector<Point> findAllPoints(Value a, Value b)
{
Value ySqr;
std::vector<Point> vec;
std::cout << "Alle Punkte fuer a = " << a << ", b = " << b << " und Prime = " << PRIME << std::endl;
// Is it an elliptic curve?
if (isEC(a, b))
{
// Test all x-Values
for (int x = 0; x <= PRIME - 1;x++)
{
// y^2
ySqr = calcEC(x, a, b);
// Test ySqr for square by root
if (testSqr(ySqr))
{
//sqrt operator ~
Value yPos = ~ySqr;
std::cout << "(" << x << "," << yPos << ")\t";
Value yNeg = yPos - (yPos * 2);
// Save found points into vector
vec.push_back(Point(x, yPos));
vec.push_back(Point(x, yNeg));
if (yNeg != 0)
std::cout << "(" << x << "," << yNeg << ")\t";
}
}
//vec.insert(vec.begin(), Point(INFINITY, INFINITY));
std::cout << std::endl;
}
else
// Not an ellpitic curve
std::cout << "\na and b are not leading to an ellptic curve.";
return vec;
}
// Test if a and b lead to an EC
int isEC(Value a, Value b)
{
if ((a ^ 3) * 4 + (b ^ 2) * 27 != 0)
return 1;
return 0;
}
// Calculate y^2
Value calcEC(int x, Value a, Value b)
{
return Value(a*x + (x ^ 3) + b);
}
// Test ySqr for square by root
int testSqr(Value ySqr)
{
if ((ySqr ^ ((PRIME - 1) / 2)) == 1 || ySqr == 0)
return 1;
return 0;
}
Tests.hpp
#pragma once
#include "Helper.hpp"
class Tests
{
public:
void twoDAdd(Value a, Value b);
void twoDDoubling(Value a, Value b);
void threeDAdd(Value a, Value b);
void threeDDoubling(Value a, Value b);
};
Tests.cpp
#pragma once
#include <stdlib.h>
#include <vector>
#include <iostream>
#include <math.h>
#include <time.h>
#include "Tests.hpp"
// 2D - Addition
void Tests::twoDAdd(Value a, Value b)
{
std::cout << "\n========== 2D Addition ==========\n";
Point p2D1 = Point(5, 22);
Point p2D2 = Point(16, 27);
std::cout << p2D1 << " + " << p2D2 << " = " << add(p2D1, p2D2, a);
std::cout << std::endl;
}
// 2D - Doubling
void Tests::twoDDoubling(Value a, Value b)
{
std::cout << "\n========== 2D Doubling ==========\n";
Point p2D1 = Point(5, 22);
std::cout << "2 * " << p2D1 << " = " << add(p2D1, p2D1, a);
std::cout << std::endl << std::endl;
}
// 3D - Addition
void Tests::threeDAdd(Value a, Value b)
{
std::cout << "\n========== 3D Addition ==========\n";
std::cout << "All points for a = " << a << ", b = " << b << " and prime = " << PRIME << std::endl;
std::vector<Point> allPoints = findAllPoints(a, b);
std::srand(time(NULL));
int random = std::rand() % (allPoints.capacity() - 1);
Point tmp = allPoints.at(random);
std::cout << std::endl << "Random Point 1: " << tmp << std::endl << std::endl;
tmp.z = 1;
Point p1 = add(tmp, tmp, a);
std::cout << p1 << std::endl;
random = std::rand() % (allPoints.capacity() - 1);
tmp = allPoints.at(random);
std::cout << std::endl << "Random Point 2: " << tmp << std::endl << std::endl;
tmp.z = 1;
Point p2 = add(tmp, tmp, a);
std::cout << p2 << std::endl;
Point p3 = add(p1, p2, a);
std::cout << p3 << std::endl;
}
// 3D - Doubling
void Tests::threeDDoubling(Value a, Value b)
{
std::cout << "\n========== 3D Doubling ==========\n";
std::cout << "All points for a = " << a << ", b = " << b << " and prime = " << PRIME << std::endl;
std::vector<Point> allPoints = findAllPoints(a, b);
int random = std::rand() % (allPoints.capacity() - 1);
Point tmp = allPoints[random];
std::cout << std::endl << "Random Point: " << tmp << std::endl << std::endl;
Point p1 = add(tmp, tmp, a);
std::cout << p1 << std::endl;
tmp.z = 1;
Point p2 = add(tmp, tmp, a);
std::cout << p2 << std::endl;
Point p3 = Point(p2.x / (p2.z ^ 2), p2.y / (p2.z ^ 3));
std::cout << p3 << std::endl;
if (p1 == p3)
std::cout << "Point p1 == Point p3" << std::endl;
else
std::cout << "Point p1 != Point p3" << std::endl;
}
Main.cpp
#pragma once
#include <stdlib.h>
#include <vector>
#include <iostream>
#include <math.h>
#include <time.h>
#include "Tests.hpp"
int PRIME = 29;
void main()
{/*
Value a = 4;
Value b = 20;
std::vector<Point> allPoints = findAllPoints(a, b);
/*
// Tests ausfuehren
twoDAdd(a, b);
twoDDoubling(a, b);
threeDAdd(a, b);
threeDDoubling(a, b);
*/
std::cout << std::endl;
system("pause");
}
Thanks in advance and please excuse my "inperfect" way of coding.
This is happening because you have function definition in header files. Every file that we'll import your header files will have a body function - this is the reason why you have this error. If you want to have the definitions inside header files, you must use inline keyword. Otherwise you need to implement them in .cpp files (the "correct" way of solving this issue).
e.g
// Test if a and b lead to an EC
inline int isEC(Value a, Value b)
{
if ((a ^ 3) * 4 + (b ^ 2) * 27 != 0)
return 1;
return 0;
}
// Calculate y^2
inline Value calcEC(int x, Value a, Value b)
{
return Value(a*x + (x ^ 3) + b);
}
// Test ySqr for square by root
inline int testSqr(Value ySqr)
{
if ((ySqr ^ ((PRIME - 1) / 2)) == 1 || ySqr == 0)
return 1;
return 0;
}
Related
I'm trying to solve this problem using the slicing technic.
But I just passed the first two test cases in this gym (Problem A)
2017-2018 ACM-ICPC East Central North America Regional Contest (ECNA 2017)
The whole step in my code looks like this:
calculate the total area using vector cross when inputting the polygon information.
find all the endpoints and intersection points, and record x value of them.
for each slice (sort x list and for each interval) find the lines from every polygon which crosses this interval and store this smaller segment.
sort segments.
for each trapezoid or triangle, calculate the area if this area is covered by some polygon.
sum them all to find the cover area.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template<typename T> using p = pair<T, T>;
template<typename T> using vec = vector<T>;
template<typename T> using deq = deque<T>;
// #define dbg
#define yccc ios_base::sync_with_stdio(false), cin.tie(0)
#define al(a) a.begin(),a.end()
#define F first
#define S second
#define eb emplace_back
const int INF = 0x3f3f3f3f;
const ll llINF = 1e18;
const int MOD = 1e9+7;
const double eps = 1e-9;
const double PI = acos(-1);
double fcmp(double a, double b = 0, double eps = 1e-9) {
if (fabs(a-b) < eps) return 0;
return a - b;
}
template<typename T1, typename T2>
istream& operator>>(istream& in, pair<T1, T2>& a) { in >> a.F >> a.S; return in; }
template<typename T1, typename T2>
ostream& operator<<(ostream& out, pair<T1, T2> a) { out << a.F << ' ' << a.S; return out; }
struct Point {
double x, y;
Point() {}
Point(double x, double y) : x(x), y(y) {}
Point operator+(const Point& src) {
return Point(src.x + x, src.y + y);
}
Point operator-(const Point& src) {
return Point(x - src.x, y - src.y);
}
Point operator*(double src) {
return Point(x * src, y * src);
}
//* vector cross.
double operator^(Point src) {
return x * src.y - y * src.x;
}
};
struct Line {
Point sp, ep;
Line() {}
Line(Point sp, Point ep) : sp(sp), ep(ep) {}
//* check if two segment intersect.
bool is_intersect(Line src) {
if (fcmp(ori(src.sp) * ori(src.ep)) < 0 and fcmp(src.ori(sp) * src.ori(ep)) < 0) {
double t = ((src.ep - src.sp) ^ (sp - src.sp)) / ((ep - sp) ^ (src.ep - src.sp));
return fcmp(t) >= 0 and fcmp(t, 1) <= 0;
}
return false;
}
//* if two segment intersect, find the intersection point.
Point intersect(Line src) {
double t = ((src.ep - src.sp) ^ (sp - src.sp)) / ((ep - sp) ^ (src.ep - src.sp));
return sp + (ep - sp) * t;
}
double ori(Point src) {
return (ep - sp) ^ (src - sp);
}
bool operator<(Line src) const {
if (fcmp(sp.y, src.sp.y) != 0)
return sp.y < src.sp.y;
return ep.y < src.ep.y;
}
};
int next(int i, int n) {
return (i + 1) % n;
}
int main()
{
yccc;
int n;
cin >> n;
//* the point list and the line list of polygons.
vec<vec<Point>> p_list(n);
vec<vec<Line>> l_list(n);
//* x's set for all endpoints and intersection points
vec<double> x_list;
//* initializing point list and line list
double total = 0, cover = 0;
for (int i = 0; i < n; i++) {
int m;
cin >> m;
p_list[i].resize(m);
for (auto &k : p_list[i]) {
cin >> k.x >> k.y;
x_list.eb(k.x);
}
l_list[i].resize(m);
for (int k = 0; k < m; k++) {
l_list[i][k].sp = p_list[i][k];
l_list[i][k].ep = p_list[i][next(k, m)];
}
//* calculate the polygon area.
double tmp = 0;
for (int k = 0; k < m; k++) {
tmp += l_list[i][k].sp.x * l_list[i][k].ep.y - l_list[i][k].sp.y * l_list[i][k].ep.x;
}
total += abs(tmp);
}
//* find all intersection points
for (int i = 0; i < n; i++)
for (int k = i+1; k < n; k++) {
for (auto li : l_list[i])
for (auto lk : l_list[k])
if (li.is_intersect(lk)) {
x_list.eb(li.intersect(lk).x);
}
}
sort(al(x_list));
auto same = [](double a, double b) -> bool {
return fcmp(a, b) == 0;
};
x_list.resize(unique(al(x_list), same) - x_list.begin());
//* for each slicing, calculate the cover area.
for (int i = 0; i < x_list.size() - 1; i++) {
vec<pair<Line, int>> seg;
for (int k = 0; k < n; k++) {
for (auto line : l_list[k]) {
//* check if line crosses this slicing
if (fcmp(x_list[i], min(line.sp.x, line.ep.x)) >= 0 and fcmp(max(line.sp.x, line.ep.x), x_list[i+1]) >= 0) {
Point sub = line.ep - line.sp;
double t_sp = (x_list[i] - line.sp.x) / sub.x, t_ep = (x_list[i+1] - line.sp.x) / sub.x;
seg.eb(Line(Point(x_list[i], line.sp.y + sub.y * t_sp), Point(x_list[i+1], line.sp.y + sub.y * t_ep)), k);
}
}
}
//* sort this slicing
sort(al(seg));
deq<bool> inside(n);
int count = 0;
Line prev;
// cout << x_list[i] << ' ' << x_list[i+1] << endl;
//* calculate cover area in this slicing.
for (int k = 0; k < seg.size(); k++) {
if (count)
cover += ((seg[k].F.sp.y - prev.sp.y) + (seg[k].F.ep.y - prev.ep.y)) * (x_list[i+1] - x_list[i]);
prev = seg[k].F;
// cout << seg[k].S << ": (" << seg[k].F.sp.x << ", " << seg[k].F.sp.y << "), (" << seg[k].F.ep.x << ", " << seg[k].F.ep.y << ")" << endl;
inside[k] = !inside[k];
count += (inside[k] ? 1 : -1);
}
}
//* answer
cout << total / 2 << ' ' << cover / 2;
}
I can't not figure out which part I made a mistake :(
I keep getting an error of "Expression: crtlsvalidHeapPointer(block)"
When I run the program, it executes all the way to the end but it triggers this error.
I believe I created big three expression. making deep copying and deleting previous address.
Is there I am missing point of creating big three expression?
#include <iostream>
using namespace std;
//between 0 and 255
class color {
int *red, *green, *blue;
public:
color() {
red = new int; green = new int; blue = new int;
*red = 0; *green = 0; *blue = 0; }
color(int r, int g, int b) {
if (r < 0 || r>255)
r = 0;
if (g < 0 || g>255)
g = 0;
if (b < 0 || b>255)
b = 0;
red = new int;
green = new int;
blue = new int;
*red = r;
*green = g;
*blue = b;
}
color(const color &rhs) :red(new int), green(new int), blue(new int) { *this = rhs; }
color & operator=(const color &rhs) {
if (this == &rhs)
return *this;
delete red;
delete green;
delete blue;
red = rhs.red;
green = rhs.green;
blue = rhs.blue;
return *this;
}
~color() {
delete red;
delete green;
delete blue;
};
color & operator +(const color & rhs) {
int r, g, b;
r = *red + *rhs.red;
if (r > 255)
r = 255;
g = *green + *rhs.green;
if (g > 255)
g = 255;
b = *blue + *rhs.blue;
if (b > 255)
b = 255;
color *thecolor = new color(r, g, b);
return *thecolor;
}
color & operator /(const color &rhs) {
int r, g, b;
if (*red == 0 || *rhs.red == 0)
r = 0;
else
r = *red / (*rhs.red);
if (*green == 0 || *rhs.green == 0)
g = 0;
else
g = *green / (*rhs.green);
if (*blue == 0 || *rhs.blue == 0)
b = 0;
else
b = *blue / (*rhs.blue);
color *newcolor = new color(r, g, b);
return *newcolor;
}
int getred() const { return *red; }
int getgreen()const { return *green; }
int getblue() const { return *blue; }
void set_red(int r) { *red = r; }
void set_green(int g) { *green = g; }
void set_blue(int b) { *blue = b; }
friend ostream &operator <<(ostream &out, const color &c) {
out << "(" << c.getred() << ", " << c.getgreen() << ", " << c.getblue() << ")";
return out;
}
};
int main() {
color c1(100, 150, 220);
color c2(23, 100, 76);
color c3(c1);
color c4 = c2;
//testing << operator
cout << "c1: " << c1 << endl;
cout << "c2: " << c2 << endl;
cout << "c3: " << c3 << endl;
cout << "c4: " << c4 << endl;
cout << "testing + and / operators" << endl;
cout << "c1+c2: " << c1 + c2 << endl;
cout << "c1/c2: " << c1 / c2 << endl;
return 0;
}
#include <iostream>
#include <iomanip>
#include <cmath>
#include "lineType.h"
using namespace std;
int main()
{
double x, y;
double a = 1.;
double b = 0.;
double c = 1.;
double d = 2.;
double e = 0.;
double f = 3.;
double g = 0.;
double h = 4.;
double i = -1.;
lineType line1(a, b, c);
lineType line2(d, e, f);
lineType line3(g, h, i);
cout << "Line 1: ";
line1.display();
if (line1.isParallel(line2)) cout << "line1 is parallel to line 2" << endl;
if (line1.isPerp(line3)) cout << "line 1 is perpendicular to line 3" << endl;
if (line2.intersect(line3, x, y))
cout << "The intersection of lines 2 and 3 is at point(" << x << ", " << y << ")" << endl;
else
cout << "Lines 2 and 3 do not intersect." << endl;
return 0;
}
This is the code I am testing and the issue I am getting is c2661 no overloaded function takes 3 arguments
My Header file is:
#pragma once
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
class lineType
{
private:
double a;
double b;
double c;
public:
void display() const;
bool isParallel(const lineType& line) const;
bool isPerp(const lineType& line) const;
bool intersect(const lineType& line, double& x, double& y);
lineType();
lineType(double a2, double b2, double c2);
~lineType();
};
This is the lineType.cpp file that was wanted
#include "lineType.h"
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
void lineType::display() const
{
cout << a << "x + " << b << "y = " << c << endl;
}
bool lineType::isParallel(const lineType& line) const
{
if (a == 0 && line.a == 0)
return 1;
if (b == 0 && line.b == 0)
return 1;
else if (-a / b == -line.a / line.b)
return 1;
else
return 0;
}
bool lineType::isPerp(const lineType& line) const
{
if (a == 0 && line.b == 0)
return 1;
if (b == 0 && line.a == 0)
return 1;
else if (-a / b == line.b / line.a)
return 1;
else
return 0;
}
bool lineType::intersect(const lineType& line, double& x, double& y)
{
if (a == 0)
x = c / b;
if (line.a == 0)
x = line.c / line.b;
if (b == 0)
y = c / a;
if (line.b == 0)
{
y = line.c / line.a;
}
else
{
x = ((a*line.c) - (c*line.a)) / ((b*line.a) - (a*line.b));
y = ((c*line.b) - (b*line.c)) / ((b*line.a) - (a*line.b));
}
if (a == 0 && line.a == 0)
return 0;
if (b == 0 && line.b == 0)
return 0;
return 1;
}
lineType::lineType()
{
a = 0;
b = 0;
c = 0;
}
lineType::lineType(double a2, double b2, double c2)
{
a = a2;
b = b2;
c = c2;
}
lineType::~lineType()
{
}
The error message that appears
Error (active) E0289 no instance of constructor "lineType::lineType" matches the argument list Project1 line 20
Same error message for lines 21 and 22 in the source.cpp file. so I am not sure what is occuring?
lineType::lineType, which is the constructor, is implicitely generated, since you did not provide any user defined constructors. Default-generated constructors take no arguments, yet you try to provide three arguments in lines:
lineType line1(a, b, c);
lineType line2(d, e, f);
lineType line3(g, h, i);
I suspect you wanted to take advantage of aggregate initialisation, which you can't unfortunately use, since your a, b and c variables are private. You might want to add such constructor yourself:
lineType(const double a, const double b, const double c)
:a(a), b(b), c(c) { }
But that's not all. You have couple more problems with your code. Notably:
if (line1.isParallel(line2)) cout << "line1 is parallel to line 2" << endl;
contains a typo. It should be isParrallel, as declared in your class (which is also a typo) instead of isParallel. Fix either of these.
Lastly, the line:
if (line2.intersect(line3, x, y))
will not compile, since intersect() returns void, not bool. if statements require that they are provided either bools or something that's implicitely convertible to bool type. Make your function return bool, which is the logical assumption for a function that's name starts with is.
// Function as parameter of a function
#include <iostream>
#include <cmath>
#include <cassert>
using namespace std;
const double PI = 4 * atan(1.0); // tan^(-1)(1) == pi/4 then 4*(pi/4)== pi
typedef double(*FD2D)(double);
double root(FD2D, double, double); //abscissae of 2-points,
//For the algorithm to work, the function must assume values of opposite sign in these two points, check
// at point 8
double polyn(double x) { return 3 - x*(1 + x*(27 - x * 9)); }
int main() {
double r;
cout.precision(15);
r = root(sin, 3, 4);
cout << "sin: " << r << endl
<< "exactly: " << PI << endl << endl;
r = root(cos, -2, -1.5);
cout << "cos: " << r << endl
<< "exactly: " << -PI/2 << endl << endl;
r = root(polyn, 0, 1);
cout << "polyn: " << r << endl
<< "exactly: " << 1./3 << endl << endl;
/*
we look for the root of the function equivalent to function polyn
but this time defined as a lambda function
*/
r = root([](double x) -> double {
return 3 - x*(1 + x*(27 - x * 9));
}, 0, 1);
cout << "lambda: " << r << endl
<< "exactly: " << 1. / 3 << endl << endl;
return 0;
}
// Finding root of function using bisection.
// fun(a) and fun(b) must be of opposite sign
double root(FD2D fun, double a, double b) {
static const double EPS = 1e-15; // 1×10^(-15)
double f, s, h = b - a, f1 = fun(a), f2 = fun(b);
if (f1 == 0) return a;
if (f2 == 0) return b;
assert(f1*f2<0); // 8.- macro assert from header cassert.
do {
if ((f = fun((s = (a + b) / 2))) == 0) break;
if (f1*f2 < 0) {
f2 = f;
b = s;
}
else {
f1 = f;
a = s;
}
} while ((h /= 2) > EPS);
return (a + b) / 2;
}
Could somebody explain me how the loop in double root function works? I don't seem to understand 100%, I checked this bisection method online and try on paper, but I can't manage to figure it out from this example.
Thanks in advance!
It's a lot easier to understand if you split the "clever" line into multiple lines. Here's some modifications, plus comments:
double root(FD2D fun, double a, double b) {
static const double EPS = 1e-15; // 1×10^(-15)
double fa = fun(a), fb = fun(b);
// if either f(a) or f(b) are the root, return that
// nothing else to do
if (fa == 0) return a;
if (fb == 0) return b;
// this method only works if the signs of f(a) and f(b)
// are different. so just assert that
assert(fa * fb < 0); // 8.- macro assert from header cassert.
do {
// calculate fun at the midpoint of a,b
// if that's the root, we're done
// this line is awful, never write code like this...
//if ((f = fun((s = (a + b) / 2))) == 0) break;
// prefer:
double midpt = (a + b) / 2;
double fmid = fun(midpt);
if (fmid == 0) return midpt;
// adjust our bounds to either [a,midpt] or [midpt,b]
// based on where fmid ends up being. I'm pretty
// sure the code in the question is wrong, so I fixed it
if (fa * fmid < 0) { // fmid, not f1
fb = fmid;
b = midpt;
}
else {
fa = fmid;
a = midpt;
}
} while (b-a > EPS); // only loop while
// a and b are sufficiently far
// apart
return (a + b) / 2; // approximation
}
I'm attempting to make a class that holds a (in theory) infinite amount of digits using c-strings, since ints have a limit. I am having a lot of trouble with multiplication and have begun to confuse myself. I am a student, so any help and mistakes I have not caught are very appreciated. I've been playing around with just the multiplication for 4 hours now.
The current problem is that I am calculating the results right (like if you try x = 12 and y = 4, I will only get 8 from it, then the final answer becomes 7 which is odd) but it isn't storing properly.
definition:
MyInt operator* (const MyInt& x, const MyInt& y)
{
MyInt steps[x.numDigits - 1]; // Create an array of MyInts
int carry = 0; // Holds the 'carry the one'
int result, xInt, yInt; // For adding old-school
// Add each digit separately.
for (int i = 0; i < x.numDigits; i++)
{
steps[i].numDigits = y.numDigits; // set the numDigits to y's
// Resize the array to the size of numDigits
steps[i].Resize(steps[i].numDigits);
cout << "x.numDigits = " << x.numDigits << '\n'; // DELETE THESE
cout << "numDigits = " << steps[i].numDigits << '\n';
// Figure out xInt's value
xInt = C2I(x.myNumber[x.numDigits - i - 1]);
// Now multiply xInt by each digit of y
for (int j = 1; j <= y.numDigits; j++)
{
// yInt's value for this run through
yInt = C2I(y.myNumber[y.numDigits - j]);
// Answer is xInt * yInt + the remainder
result = ((xInt * yInt) + carry);
carry = 0; // Reset carry to zero
// If the result is 10 or higher, carry the excess
if (result > 9)
{
carry = result / 10;
result = result % 10;
}
// Assign result to the appropriate slot in the new number
steps[i].myNumber[(steps[i].numDigits - j)] = I2C(result);
cout << "ASSIGNED " << steps[i].myNumber[steps[i].numDigits - j] //DELETE THESE
<< " TO SLOT " << (steps[i].numDigits - j)
<< " with a rem = " << carry << '\n';
}
cout << "YOU GOT OUT OF THE J FOR LOOP\n";
// If carry wasn't reset to 0, that means the loop ended.
// This means there is a # that cannot fit in the current
// array size. We must resize, and then assign
// the extra characters into the array.
if (carry > 0)
{
int carryCopy = carry; // Copy of n for counting numDigits
int carryCount = 0; // Counts up how many digits are in carry
while(carryCopy > 0) // Figure out how many #'s there are
{
carryCopy = carryCopy / 10;
carryCount++;
}
// Figure out the new size
steps[i].numDigits = steps[i].numDigits + carryCount;
// Resize to new size
steps[i].Resize(steps[i].numDigits + carryCount);
// Copy in the new digits
for (int k = carryCount-1; k >= 0; k--)
{
steps[i].myNumber[k] = I2C(carry % 10);
carry = carry / 10;
}
}
}
cout << "What you have so far is " << steps[0] << "\n"; // DELETE
cout << "YOU GOT TO THE ADDING PART\n"; // DELETE
MyInt r = 0; // Create MyInt for total result
// Add up all of the arrays in steps[] into r
for (int l = 0; l < x.numDigits - 1; l++)
r = r + steps[l];
return r; // Result
}
Header file
#include <iostream>// for ostream, istream
using namespace std;
class MyInt
{
// these overload starters are declared as friend functions
friend MyInt operator+ (const MyInt& x, const MyInt& y);
friend MyInt operator* (const MyInt& x, const MyInt& y);
friend bool operator< (const MyInt& x, const MyInt& y);
friend bool operator> (const MyInt& x, const MyInt& y);
friend bool operator<= (const MyInt& x, const MyInt& y);
friend bool operator>= (const MyInt& x, const MyInt& y);
friend bool operator== (const MyInt& x, const MyInt& y);
friend bool operator!= (const MyInt& x, const MyInt& y);
friend ostream& operator<< (ostream& s, const MyInt& n);
friend istream& operator>> (istream& s, MyInt& n);
public:
MyInt(int n = 0); // first constructor
MyInt(const char * n); // second constructor
~MyInt(); // Destructor
MyInt(const MyInt & n); // Copy Constructor
MyInt& operator= (const MyInt & n); // Assignment operator
// be sure to add in the second constructor, and the user-defined
// versions of destructor, copy constructor, and assignment operator
private:
// member data (suggested: use a dynamic array to store the digits)
unsigned int numDigits; // The number of digits in myInt
char * myNumber; // Pointer to dynamic array of digits
void Resize(unsigned int newSize); // Resize array
};
and the main program I am using to test:
int main()
{
// demonstrate behavior of the two constructors and the << overload
MyInt x(12345), y("9876543210123456789"), r1(-1000), r2 = "14H67", r3;
char answer;
cout << "Initial values: \nx = " << x << "\ny = " << y
<< "\nr1 = " << r1 << "\nr2 = " << r2 << "\nr3 = " << r3 << "\n\n";
// demonstrate >> overload
cout << "Enter first number: ";
cin >> x;
cout << "Enter second number: ";
cin >> y;
cout << "You entered:\n";
cout << " x = " << x << '\n';
cout << " y = " << y << '\n';
// demonstrate assignment =
cout << "Assigning r1 = y ...\n";
r1 = y;
cout << " r1 = " << r1 << '\n';
// demonstrate comparison overloads
if (x < y) cout << "(x < y) is TRUE\n";
if (x > y) cout << "(x > y) is TRUE\n";
if (x <= y) cout << "(x <= y) is TRUE\n";
if (x >= y) cout << "(x >= y) is TRUE\n";
if (x == y) cout << "(x == y) is TRUE\n";
if (x != y) cout << "(x != y) is TRUE\n";
// demonstrating + and * overloads
r1 = x + y;
cout << "The sum (x + y) = " << r1 << '\n';
r2 = x * y;
cout << "The product (x * y) = " << r2 << "\n\n";
cout << "The sum (x + 12345) = " << x + 12345 << '\n';
cout << "The product (y * 98765) = " << y * 98765 << '\n';
}
You're doing all the multiplication first, then the adding. This is inefficient and makes your code more complicated.
Instead, you should add the results together as you compute each multiply stage.
For example, instead of:
A = 123
B = 456
S[0] = A * (B[2] * 10^2) = 123 * 400 = 49200
S[1] = A * (B[1] * 10^1) = 123 * 50 = 6150
S[2] = A * (B[0] * 10^0) = 123 * 6 = 738
R = S[0] + S[1] + S[2] = 49200 + 6150 + 738 = 56088
do this:
A = 123
B = 456
R = 0
R += A * (B[2] * 10^2) = 0 + 123 * 400 = 49200
R += A * (B[1] * 10^1) = 49200 + 123 * 50 = 55350
R += A * (B[0] * 10^0) = 55350 + 123 * 6 = 56088
This gets rid of the need for the steps array (S in my example).
Also, consider storing the digits in your array least-significant-digit first. This allows you to replace the * 10^N steps with index shifts.
A = 123
B = 456
R = 0
R[0:] += A * B[0] = 123 * 6 = 738()
R[1:] += A * B[1] = 123 * 5 + 73 = 688(8)
R[2:] += A * B[2] = 123 * 4 + 68 = 560(88)
Where the () part is the digits shifted past by the indexing of R. This technique also makes it easier to add or remove most-significant-digits since they're at the end of the array and not the beginning.
One thing I notice is that steps is initialized with a size of x.numDigits - 1 but your for loops goes past the end of the array. Perhaps you meant this steps should be of size x.numDigits. There may be other bugs than just this.