2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 OMP , разные значения сумм.
Сообщение05.04.2025, 03:18 


03/12/24
20
Задача такая: Определить класс CIntN для работы с целыми знаковыми числами, состоящими lо N десятичных цифр, где N задается в конструкторе.
В классе должны быть определены необходимые конструкторы, деструктор, операторы присваивания, сложения, вычитания.
Написать функцию и конструктор сохранения переменной данного типа в файл и загрузки из файла. В отдельном файле должен быть написан тест на данный класс.

В процессе сдачи преподаватель попросил переписать тип данных на входе из char в String. Но почему-то теперь неверные значения сумм выходят. Никак не получается найти ошибку. Помогите, пожалуйста, советом


func.cpp
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include <string>
#include "func.h"
using namespace std;
vector<CIntN*> input(string sf)
{
        vector<CIntN*> nums;
        ifstream fin(sf);
        string str;
        if (fin.is_open())
        {
            string str;
                for (; getline(fin, str);)
                {

                        char type = str[0];
                        string number=str.substr(2);
                        if (type=='0')
                        {
                                CIntN* num = new CIntN0(number);
                                nums.push_back(num);
                                //delete num;
                        }
                        else
                        {
                                CIntN* num = new CIntN1(number);
                                nums.push_back(num);
                                //delete num;
                        }
                }
                fin.close();
        }
        return nums;
}
CIntN0 sum(vector<CIntN*> t)
{
        const int n = t.size();
        CIntN0 res("0");
        for (int i = 0; i < n; i++)
        {
            res += *t[i];
        }
        return res;
}
CIntN0 sumOmp(vector<CIntN*> t)
{
        const int n = t.size();
        CIntN0 res("0");
#pragma omp declare reduction(+:CIntN:omp_out=omp_out+omp_in)//initializer(omp_priv=omp_orig)
#pragma omp parallel for reduction(+:res)
        for (int i = 0; i < n; i++)
        {
            res = res + *t[i];
        }
        return res;
}
void CIntGen(const int n, int max)
{
        ofstream fout("input.txt");
        for (int i = 0; i < n; i++)
        {
                fout << rand() % 2 << ' ' << rand() % max << '\n';
        }
        fout << 0 << ' ' << 0 << '\0';
        fout.close();
}
void output(vector<CIntN*> t)
{
        for (auto it=t.begin();it!=t.end();++it)
        {
                CIntN* td = *it;
                td->output();
        }
}
 


CIntN.cpp
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include "CIntN.h"
CIntN::CIntN(string number)
{
        setZero();
        if (number.length())
        {
                int j = 0;
                if (number[0] == '-')
                {
                        sign = '-';
                        num = new int[this->n = number.length() - 1];
                        for (int i = n; i > 0; i--) { num[j] = (int)number[i] - 48; j++; }
                }
                else
                {
                        sign = '+';
                        num = new int[this->n = number.length()];
                        for (int i = n - 1; i > -1; i--) { num[j] = (int)number[i] - 48; j++; }
                }
        }
}
CIntN CIntN::operator+(const CIntN& b)
{
        int N;
        if (n >= b.n) N = n + 1;
        else N = b.n + 1;
        CIntN x = N; x.sign = sign;
        for (int i = 0; i < n; i++)     x.num[i] = num[i];
        for (int i = n; i < N; i++) x.num[i] = 0;
        CIntN y = N; y.sign = b.sign;
        for (int i = 0; i < b.n; i++) y.num[i] = b.num[i];
        for (int i = b.n; i < N; i++) y.num[i] = 0;
        CIntN res = N;
        if (x.sign == y.sign)
        {
                res.sign = x.sign;
                for (int i = 0; i < N; i++)
                {
                        if (x.num[i] + y.num[i] > 9)
                        {
                                for (int j = i + 1; j < N; j++) if (x.num[j] != 9) { x.num[i + 1]++; break; }
                        }
                        res.num[i] = (x.num[i] + y.num[i]) % 10;
                }
        }
        else
        {
                if (x.sign == '+') { y.sign = '+'; return x - y; }
                else { x.sign = '+'; return y - x; }
        }
        for (int i = N - 1; i > -1; i--)
        {
                if (res.num[i] == 0) N--;
                else break;
        }
        CIntN c = N; c.sign = res.sign;
        for (int i = 0; i < N; i++) c.num[i] = res.num[i];
        return c;
}
CIntN CIntN::operator-(const CIntN& b)
{
        int N;
        if (n >= b.n) N = n;
        else N = b.n;
        CIntN x = N; x.sign = sign;
        for (int i = 0; i < n; i++)     x.num[i] = num[i];
        for (int i = n; i < N; i++) x.num[i] = 0;
        CIntN y = N; y.sign = b.sign;
        for (int i = 0; i < b.n; i++) y.num[i] = b.num[i];
        for (int i = b.n; i < N; i++) y.num[i] = 0;
        CIntN res = N;
        if (x.sign == y.sign)
        {
                if (x > y)
                {
                        res.sign = x.sign;
                        for (int i = 0; i < N; i++)
                        {
                                if (x.num[i] - y.num[i] < 0)
                                {
                                        int j = i + 1;
                                        while (x.num[j] == 0 && j < N) { x.num[j] = 9; j++; }
                                        if (j < N)
                                        {
                                                x.num[j]--;
                                                res.num[i] = x.num[i] + 10 - y.num[i];
                                        }
                                        else { for (j = 0; j < N; j++) { res.num[j] = 0; } break; }
                                }
                                else res.num[i] = x.num[i] - y.num[i];
                        }
                }
                else if (x < y)
                {
                        res.sign = '-';
                        for (int i = 0; i < N; i++)
                        {
                                if (y.num[i] - x.num[i] < 0)
                                {
                                        int j = i + 1;
                                        while (y.num[j] == 0 && j < N) { y.num[j] = 9; j++; }
                                        if (j < N)
                                        {
                                                y.num[j]--;
                                                res.num[i] = y.num[i] + 10 - x.num[i];
                                        }
                                        else { for (j = 0; j < N; j++) { res.num[j] = 0; } break; }
                                }
                                else res.num[i] = y.num[i] - x.num[i];
                        }
                }
                else
                {
                        CIntN c = 1;
                        c.num[0] = 0;
                        return c;
                }
        }
        else
        {
                if (x.sign == '+') { y.sign = '+'; return x + y; }
                else { y.sign = '-'; return x + y; }
        }
        for (int i = N - 1; i > -1; i--)
        {
                if (res.num[i] == 0) N--;
                else break;
        }
        CIntN c = N; c.sign = res.sign;
        for (int i = 0; i < N; i++) c.num[i] = res.num[i];
        return c;
}
CIntN CIntN::operator+=(const CIntN& b)
{
        int N;
        if (n >= b.n) N = n + 1;
        else N = b.n + 1;
        CIntN x = N; x.sign = sign;
        for (int i = 0; i < n; i++) x.num[i] = num[i];
        for (int i = n; i < N; i++) x.num[i] = 0;
        CIntN y = N; y.sign = b.sign;
        for (int i = 0; i < b.n; i++) y.num[i] = b.num[i];
        for (int i = b.n; i < N; i++) y.num[i] = 0;
        CIntN res = N;
        if (x.sign == y.sign)
        {
                res.sign = x.sign;
                for (int i = 0; i < N; i++)
                {
                        if (x.num[i] + y.num[i] > 9)
                        {
                                for (int j = i + 1; j < N; j++) if (x.num[j] != 9) { x.num[i + 1]++; break; }
                        }
                        res.num[i] = (x.num[i] + y.num[i]) % 10;
                }
        }
        else
        {
                if (x.sign == '+') { y.sign = '+'; return x - y; }
                else { x.sign = '+'; return y - x; }
        }
        for (int i = N - 1; i > -1; i--)
        {
                if (res.num[i] == 0) N--;
                else break;
        }
        CIntN c = N; c.sign = res.sign;
        for (int i = 0; i < N; i++) c.num[i] = res.num[i];
        *this=c;
        return *this;
}
bool CIntN::operator>(const CIntN& b)
{
        if (n == b.n)
        {
                for (int i = n - 1; i > -1; i--) if (num[i] != b.num[i]) return num[i] > b.num[i];
        }
        else return n > b.n;
        return false;
}
bool CIntN::operator<(const CIntN& b)
{
        if (n == b.n)
        {
                for (int i = n - 1; i > -1; i--) if (num[i] != b.num[i]) return num[i] < b.num[i];
        }
        else return n < b.n;
        return false;
}
string CIntN::makeStr()
{
        string num = "";
        if (sign == '-') num += '-';
        for (int i = n - 1; i > -1; i--) num += (this->num[i] + 48);
        return num;
}
void CIntN::output()
{
        if (sign == '-') cout << sign;
        for (int i = n - 1; i > -1; i--) cout << num[i];
        cout << endl;
}
void CIntN::print()
{
        if (sign == '-') cout << sign;
        for (int i = n - 1; i > -1; i--) cout << num[i];
        cout << endl;
}


CIntN.h
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#pragma once
#include <iostream>
#include <fstream>
#include <istream>
#include <string.h>
using namespace std;
class CIntN
{
private:
        int* num; int n; char sign;
public:
        //---
        CIntN() { setZero(); }
        CIntN(int n) { setZero(); if (n) num = new int[this->n = n]; sign = '+'; }
        CIntN(const CIntN& b) { copyOnly(b); }
        CIntN(CIntN&& b) { n = b.n; num = b.num; sign = b.sign; b.setZero(); }
        CIntN(string number);
        CIntN& operator=(const CIntN& b) { if (&b != this) { clean(); copyOnly(b); } return *this; }
        CIntN& operator=(CIntN&& b) { if (&b != this) { clean(); n = b.n; sign = b.sign; num = b.num; b.setZero(); } return *this; }
        virtual ~CIntN() { clean(); }
        //---
        void setZero() { num = nullptr; n = 0; sign = ' '; }
        void clean() { delete[] num; setZero(); }
        void copyOnly(const CIntN& b) { setZero(); if (b.size()) { memcpy(num = new int[n = b.n], b.num, b.n * sizeof(*num)); } sign = b.sign; }
        //---
        string makeStr();
        virtual void output();
        void print();
        //---
        size_t size() const { return n; }
        CIntN operator+(const CIntN& b);
        CIntN operator-(const CIntN& b);
        CIntN operator+=(const CIntN& b);
        bool operator>(const CIntN& b);
        bool operator<(const CIntN& b);
};



CIntN0.cpp
Используется синтаксис C++
#include "CIntN0.h"
void CIntN0::output()
{
        ofstream fout("output0.txt",ios::app);
        fout << makeStr() << endl;
        fout.close();
}



CIntN0.h
Используется синтаксис C++
#pragma once
#include "CIntN.h"
class CIntN0 :
    public CIntN
{
public:
    CIntN0() :CIntN() {}
    CIntN0(int n) : CIntN(n) {}
    CIntN0(const CIntN& b) : CIntN(b) {}
    CIntN0(CIntN&& b) : CIntN(b) {}
    CIntN0(string number) :CIntN(number) {}
    void output();
};
 



CIntN1.cpp
Используется синтаксис C++
#include "CIntN1.h"
void CIntN1::output()
{
        ofstream fout("output1.txt",ios::app);
        fout << makeStr() << ' ';
        fout.close();
}


CIntN1.h
Используется синтаксис C++
[#pragma once
#include "CIntN.h"
class CIntN1 :
    public CIntN
{
public:
    CIntN1() :CIntN() {}
    CIntN1(int n) : CIntN(n) {}
    CIntN1(const CIntN& b) : CIntN(b) {}
    CIntN1(CIntN&& b) : CIntN(b) {}
    CIntN1(string number) :CIntN(number) {}
    void output();
};
 


func.h
Используется синтаксис C++
#pragma once
#include <vector>
#include <omp.h>
#include <time.h>
#include "CIntN0.h"
#include "CIntN1.h"
vector<CIntN*> input(string sf);
CIntN0 sum(vector<CIntN*> t);
CIntN0 sumOmp(vector<CIntN*> t);
void CIntGen(const int n, int max);
void CIntGenOmp(const int n, int max);
void output(vector<CIntN*> t);


main.cpp
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include "func.h"
int main(void)
{
    srand(time(NULL));
        time_t t1, t2, dt1;
        CIntGen(100000000, 1000000);
        vector<CIntN*> tn = input("input.txt");
        t1 = clock();
        sum(tn).print();
        t2 = clock();
        dt1 = (t2 - t1);
        cout << "Without OMP: " << dt1 << endl;
        for(auto &p:tn)
        {
            delete p;
            p=nullptr;
        }
        tn = input("input.txt");
        t1 = clock();
        sumOmp(tn).print();
        t2 = clock();
        dt1 = (t2 - t1);
        cout << "With OMP: " << dt1 << endl;
        for(auto &p:tn)
        {
            delete p; p=nullptr;
        }

        return 0;
}

 Профиль  
                  
 
 Re: OMP , разные значения сумм.
Сообщение14.04.2025, 17:56 
Аватара пользователя


28/10/21
103
А в чем назначение вот этого ветвления при чтении чисел

Код:
                        char type = str[0];
                        string number=str.substr(2);
                        if (type=='0')


Что это за "типы" чисел и где все это описано в условии задачи?

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 2 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group