经验分享
  • 板块学术版
  • 楼主Tony20120213
  • 当前回复6
  • 已保存回复6
  • 发布时间2024/7/7 12:39
  • 上次更新2024/7/7 15:37:58
查看原帖
经验分享
1284890
Tony20120213楼主2024/7/7 12:39

高精度头文件: high.h:

#include <iostream>
#include <cstring>

#ifndef UNTITLED_HIGH_H
#define UNTITLED_HIGH_H

#endif //UNTITLED_HIGH_H

int num_size(long long num);

class High
{
private:
    char num[5000];
    int size;
    bool is_neg;
public:
    High();
    High(long long num1);
    High(High& num1);

    High operator +(const High& num2) const;

    High operator -(const High& num2) const;

    High operator *(const High& num2) const;

    High operator /(const High& num2) const;

    High operator %(const High& num2) const;

    bool operator ==(const High& num2) const;

    bool operator !=(const High& num2) const;

    bool operator >(const High& num2) const;

    bool operator <(const High& num2) const;

    bool operator >=(const High& num2) const;

    bool operator <=(const High& num2) const;

    friend High pow(High num, int n);
    friend High high_rand(High begin, High end);
    friend void swap(High& num1, High& num2);


    High& operator +=(const High& num2);

    High& operator -=(const High& num2);

    High& operator *=(const High& num2);

    High& operator /=(const High& num2);

    High& operator %=(const High& num2);

    High operator ++();
    High operator --();

    High& input();
    High& print(const std::string& behind);

    High& get_long();

    High abs() const;
    High sqrt() const;

    friend std::istream& operator >>(std::istream& in, High& num1);
    friend std::ostream& operator <<(std::ostream& out, High& num1);
};

high.cpp

#include "high.h"

High::High() {
    for (int i = 0; i < 5000; ++i)
        num[i] = 0;
    size = 1;
    is_neg = false;
}

High::High(long long num1) {
    for (int i = 0; i < 5000; ++i)
        num[i] = 0;
    size = num_size(num1);
    if (num1 < 0)
        is_neg = true;
    else
        is_neg = false;
    for (int i = 0; i < size; ++i) {
        num[i] = num1 % 10;
        num1 /= 10;
    }
    if (size == 0)
        size = 1;
}

High::High(High& num1)
    : size(num1.size)
    , is_neg(num1.is_neg)
{
    for (int i = 0; i < 5000; ++i)
        num[i] = num1.num[i];
}

High High::operator +(const High& num2) const
{
    High ans;
    ans = *this;

    if (!ans.is_neg && !num2.is_neg || ans.is_neg && num2.is_neg) {
        ans.size = std::max(size, num2.size);
        for (int i = 0; i < std::max(size, num2.size); ++i) {
            ans.num[i] += num2.num[i];
            if (ans.num[i] > 9) {
                if (i == ans.size - 1)
                    ++ans.size;
                ans.num[i + 1] += ans.num[i] / 10;
                ans.num[i] %= 10;
            }
        }
    } else {
        High temp;
        temp = num2;
        if (ans.is_neg)
            swap(ans, temp);
        char ans_big = -1;
        if (ans.size > temp.size) {
            ans_big = 1;
        } else if (ans.size < temp.size) {
            ans_big = 0;
        } else if (ans.size == temp.size) {
            for (int i = ans.size - 1; i >= 0; --i) {
                if (ans.num[i] > temp.num[i]) {
                    ans_big = 1;
                    break;
                } else if (ans.num[i] < temp.num[i]) {
                    ans_big = 0;
                    break;
                }
            }
        }
        if (ans_big == -1) {
            for (int i = 0; i < ans.size; ++i) {
                ans.num[i] = 0;
            }
            ans.size = 1;
            ans.is_neg = false;

            return ans;
        }
        if (!ans_big)
            ans = temp;
        for (int i = 0; i < ans.size; ++i) {
            ans.num[i] -= temp.num[i];
            if (ans.num[i] < 0) {
                --ans.num[i + 1];
                ans.num[i] += 10;
            }
        }
        ans.get_long();
    }

    return ans;
}

High High::operator -(const High& num2) const
{
    High ans;
    ans = *this;
    bool ans_big = true;

    if (ans.size > num2.size) {
        ans_big = true;
    } else if (ans.size < num2.size) {
        ans_big = false;
    } else {
        for (int i = ans.size - 1; i >= 0; --i) {
            if (ans.num[i] > num2.num[i]) {
                ans_big = true;
                break;
            } else if (ans.num[i] < num2.num[i]) {
                ans_big = false;
                break;
            }
        }
    }

    if (!ans.is_neg && !num2.is_neg || ans.is_neg && num2.is_neg) {
        if (ans_big) {
            for (int i = 0; i < ans.size; ++i) {
                ans.num[i] -= num2.num[i];
                if (ans.num[i] < 0) {
                    --ans.num[i + 1];
                    ans.num[i] += 10;
                }
            }
            ans.get_long();
        } else {
            High temp;
            temp = num2;
            swap(ans, temp);
            if (ans.is_neg)
                ans.is_neg = false;
            else
                ans.is_neg = true;
            for (int i = 0; i < ans.size; ++i) {
                ans.num[i] -= temp.num[i];
                if (ans.num[i] < 0) {
                    --ans.num[i + 1];
                    ans.num[i] += 10;
                }
            }
            ans.get_long();
        }
    } else {
        ans.size = std::max(size, num2.size);
        for (int i = 0; i < std::max(size, num2.size); ++i) {
            ans.num[i] += num2.num[i];
            if (ans.num[i] > 9) {
                if (i == ans.size - 1)
                    ++ans.size;
                ans.num[i + 1] += ans.num[i] / 10;
                ans.num[i] %= 10;
            }
        }
    }

    return ans;
}

High High::operator *(const High& num2) const
{
    High ans;

    for (int i = 0; i < num2.size; ++i) {
        High tmp;
        tmp.is_neg = false;
        tmp.size = 0;
        for (int j = 0; j < i; ++j) {
            tmp.num[j] = 0;
            ++tmp.size;
        }
        tmp.size += size;
        for (int j = i, k = 0; k < size; ++k, ++j)
            tmp.num[j] = num[k];
        tmp.get_long();
        char tmp_2 = 0;
        for (int j = i; j < tmp.size; ++j) {
            tmp.num[j] *= num2.num[i];
            tmp.num[j] += tmp_2;
            tmp_2 = 0;
            if (tmp.num[j] > 9) {
                if (j == tmp.size - 1)
                    ++tmp.size;
                tmp_2 = tmp.num[j] / 10;
                tmp.num[j] %= 10;
            }
        }
        ans += tmp;
    }
    if (is_neg && num2.is_neg || !is_neg && !num2.is_neg)
        ans.is_neg = false;
    else
        ans.is_neg = true;

    return ans;
}

High High::operator /(const High& num2) const
{
    High temp;
    temp = *this;
    if (temp.abs() < num2.abs())
        return 0;

    High ans;
    ans.size = size - num2.size + 1;
    High temp2;
    for (int i = ans.size - 1; i >= 0; --i) {
        High temp_sum;
        temp2.size = temp.size - i;
        for (int j = temp.size - 1, k = temp2.size - 1; k >= 0; --j, --k)
            temp2.num[k] = temp.num[j];
        temp2.get_long();
        while (temp2 >= num2) {
            temp2 -= num2;
            temp_sum += num2;
            ++ans.num[i];
        }
        temp -= pow(High(10), i) * temp_sum;
    }
    ans.get_long();
    ans.is_neg = !(is_neg == num2.is_neg);

    return ans;
}

High High::operator %(const High& num2) const
{
    High ans;
    ans.size = size;
    ans.is_neg = is_neg;
    for (int i = 0; i < size; ++i)
        ans.num[i] = num[i];

    ans -= ans / num2 * num2;

    return ans;
}

bool High::operator ==(const High& num2) const
{
    High temp = *this - num2;
    if (temp.size == 1 && temp.num[0] == 0)
        return true;
    else
        return false;
}

bool High::operator !=(const High& num2) const
{
    if (!(*this == num2))
        return true;
    return false;
}

bool High::operator >(const High& num2) const
{
    High temp = *this - num2;
    if (temp != 0 && !temp.is_neg)
        return true;
    return false;
}

bool High::operator <(const High& num2) const
{
    High temp = num2 - *this;
    if (temp != 0 && !temp.is_neg)
        return true;
    return false;
}

bool High::operator >=(const High& num2) const
{
    if (!(*this < num2))
        return true;
    return false;
}

bool High::operator <=(const High& num2) const
{
    if (!(*this > num2))
        return true;
    return false;
}

High pow(High num, int n)
{
    High ans = 1;

    for (int i = 0; i < n; ++i)
        ans *= num;

    return ans;
}

High high_rand(High begin, High end)
{
    High temp = rand() % 10;

    for (int i = 1; i < 5000; ++i) {
        temp *= 10;
        temp.num[0] = rand() % 10;
    }

    temp %= (end - begin + 1) + begin;

    return temp;
}

void swap(High& num1, High& num2)
{
    High temp = num1;
    num1 = num2;
    num2 = temp;
}

High& High::operator +=(const High& num2)
{
    *this = *this + num2;

    return *this;
}

High& High::operator -=(const High& num2)
{
    *this = *this - num2;

    return *this;
}

High& High::operator *=(const High& num2)
{
    *this = *this * num2;

    return *this;
}

High& High::operator /=(const High& num2)
{
    *this = *this / num2;

    return *this;
}

High& High::operator %=(const High& num2)
{
    *this = *this % num2;

    return *this;
}

High High::operator ++()
{
    *this += 1;

    return *this;
}

High High::operator --()
{
    *this -= 1;

    return *this;
}

High& High::input()
{
    std::string tmp = "";

    std::cin >> tmp;
    memset(num, 0, 5000);

    size = tmp.size();
    if (tmp[0] == '-') {
        is_neg = true;
        --size;
        int size_tmp = tmp.size();
        for (int i = 0; i < size_tmp; ++i)
            tmp[i] = tmp[i + 1];
    } else {
        is_neg = false;
    }
    for (int i = 0, j = size - 1; i < size; ++i, --j)
        num[i] = tmp[j] - '0';

    return *this;
}

High& High::print(const std::string& behind)
{
    if (is_neg)
        printf("-");
    for (int i = size - 1; i >= 0; --i) {
        printf("%d", num[i]);
    }
    std::cout << behind;

    return *this;
}

High& High::get_long()
{
    while (num[size - 1] == 0 && size > 1)
        --size;

    return *this;
}

High High::abs() const
{
    High temp;
    temp = *this;

    temp.is_neg = false;

    return temp;
}

High High::sqrt() const
{
    High right, left = 0;
    right = *this;
    High mid;

    while (left <= right) {
        mid = (left + right + 1) / 2;
        if (pow(mid, 2) >= *this)
            right = mid - 1;
        else
            left = mid + 1;
    }

    if (pow(left, 2) > *this)
        --left;

    return left;
}

int num_size(long long num)
{
    int count = 0;

    while (num) {
        num /= 10;
        ++count;
    }

    return count;
}

std::istream& operator >>(std::istream& in, High& num1)
{
    std::string tmp = "";

    in >> tmp;
    num1 = 0;

    num1.size = tmp.size();
    if (tmp[0] == '-') {
        num1.is_neg = true;
        --num1.size;
        int size_tmp = tmp.size();
        for (int i = 0; i < size_tmp; ++i)
            tmp[i] = tmp[i + 1];
    } else {
        num1.is_neg = false;
    }
    for (int i = 0, j = num1.size - 1; i < num1.size; ++i, --j)
        num1.num[i] = tmp[j] - '0';

    return in;
}

std::ostream& operator <<(std::ostream& out, High& num1)
{
    if (num1.is_neg)
        out << "-";
    for (int i = num1.size - 1; i >= 0; --i) {
        out << num1.num[i];
    }

    return out;
}

可以直接用+-*/%运算符,输入输出可以cin,cout,也可以用里面我自己写的函数,get_long没用的,只是在其他有用的函数里要用到,num_size是一个整数的长度,一般也不需要用,不过最重要的函数里要用到它 sqrt有bug

2024/7/7 12:39
加载中...