详解C/C++高精度算法的简单实现

详解C/C++高精度算法的简单实现

简介

高精度算法是指在计算机上处理大数(比int、long long等数据类型的范围还要大)时,用特殊的算法进行计算的技术,它可以大大提高程序的精度。本文将详细讲解在C/C++语言中实现高精度算法的方法。

实现思路

实现高精度算法的主要思路是将大数拆分成多个小数,每个小数用数组存储数据,然后借助数组的运算来实现对大数的计算。下面是一些常用的方法:

  1. 将数字转换成数组。例如:数字1937可转换为数组{1,9,3,7}来进行计算。
  2. 实现数组的加减乘除运算。算法的本质是遵循竖式运算法则,一边相加、相减、相乘、相除,一边进位、退位、进位等操作,类似于小学两位数的竖式运算。
  3. 将结果数组转换成数字。例如:数组{1,9,3,7}的值为1937。

实现代码

数字转数组

void numToArr(int num, int* arr, int& len) {
    len = 0;
    while (num) {
        arr[len++] = num % 10;
        num /= 10;
    }
    reverse(arr, arr + len);  // 反转数组
}

数组转数字

int arrToNum(int* arr, int len) {
    int sum = 0;
    for (int i = 0; i < len; i++) {
        sum = sum * 10 + arr[i];
    }
    return sum;
}

高精度加法

void highAdd(int* a, int* b, int* c, int len1, int len2, int& len3) {
    len3 = max(len1, len2);
    int carry = 0;
    for (int i = 0; i < len3; i++) {
        int sum = carry;
        if (i < len1) sum += a[len1 - i - 1];
        if (i < len2) sum += b[len2 - i - 1];
        c[i] = sum % 10;
        carry = sum / 10;
    }
    if (carry != 0) {
        c[len3] = carry;
        len3++;
    }
}

高精度减法

void highSub(int* a, int* b, int* c, int len1, int len2, int& len3) {
    len3 = max(len1, len2);
    int carry = 0;
    for (int i = 0; i < len3; i++) {
        int diff = carry;
        if (i < len1) diff += a[len1 - i - 1];
        if (i < len2) diff -= b[len2 - i - 1];
        if (diff < 0) {
            carry = -1;
            c[i] = diff + 10;
        } else {
            carry = 0;
            c[i] = diff;
        }
    }
    while (len3 > 1 && c[len3 - 1] == 0) len3--; // 去掉高位的0
}

高精度乘法

void highMul(int* a, int* b, int* c, int len1, int len2, int& len3) {
    len3 = len1 + len2;
    memset(c, 0, len3 * sizeof(int)); // 初始化为0
    for (int i = 0; i < len1; i++) {
        for (int j = 0; j < len2; j++) {
            c[i + j] += a[i] * b[j];
            c[i + j + 1] += c[i + j] / 10;
            c[i + j] %= 10;
        }
    }
    while (len3 > 1 && c[len3 - 1] == 0) len3--; // 去掉高位的0
}

高精度除法

void highDiv(int* a, int b, int* c, int len1, int& len3) {
    len3 = len1;
    long long tmp = 0; // 用long long存储计算结果,避免溢出
    for (int i = 0; i < len1; i++) {
        tmp = tmp * 10 + a[i];
        c[i] = tmp / b;
        tmp %= b;
    }
    while (len3 > 1 && c[len3 - 1] == 0) len3--; // 去掉高位的0
}

示例说明

示例1:计算阶乘

// 阶乘计算(利用高精度)
int main() {
    const int MAXN = 1000;
    int a[MAXN], b[MAXN], c[MAXN], d[MAXN], len1, len2, len3, len4;
    int n;
    scanf("%d", &n);
    numToArr(1, a, len1);
    for (int i = 1; i <= n; i++) {
        numToArr(i, b, len2);
        highMul(a, b, c, len1, len2, len3);
        memcpy(a, c, len3 * sizeof(int)); // 等价于 for (int j = 0; j < len3; j++) a[j] = c[j];
        len1 = len3;
    }
    printf("%d! = ", n);
    for (int i = len1 - 1; i >= 0; i--) {
        printf("%d", a[i]);
    }
    printf("\n");
    return 0;
}

输入:n=5.

输出:5!=120.

示例2:计算斐波那契数列

// 斐波那契数列(利用高精度)
int main() {
    const int MAXN = 1000;
    int a[MAXN], b[MAXN], c[MAXN], len1, len2, len3;
    int n;
    scanf("%d", &n);
    numToArr(1, a, len1);
    numToArr(1, b, len2);
    for (int i = 3; i <= n; i++) {
        highAdd(a, b, c, len1, len2, len3);
        memcpy(a, b, len2 * sizeof(int));
        memcpy(b, c, len3 * sizeof(int));
        len1 = len2;
        len2 = len3;
    }
    printf("Fibonacci(%d) = ", n);
    for (int i = len3 - 1; i >= 0; i--) {
        printf("%d", c[i]);
    }
    printf("\n");
    return 0;
}

输入:n=7.

输出:Fibonacci(7)=13.

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解C/C++高精度算法的简单实现 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • EIZO CS2731显示器评测 原来好显示器是这样的

    EIZO CS2731显示器评测:原来好显示器是这样的 一、引言 EIZO CS2731是一款高级的色彩管理显示器,它使用了WideGamut LED面板,能提供高达99%的Adobe RGB色彩覆盖率,以及100%sRGB色彩覆盖率。这款显示器的宽屏比例和解析度,以及内置的色彩校准器和LUT表,使其尤为适合专业的照片编辑、视频编辑和图形设计人员使用。接下来…

    C 2023年5月22日
    00
  • C语言基础知识分享续篇

    C语言基础知识分享续篇 一、数据类型 1.基本数据类型 C语言中基本数据类型有以下5种: 整型(int):用来表示整数。 浮点型(float,double):用来表示小数。 字符型(char):用来表示单个字符。 空类型(void):无返回值的函数的返回类型。 布尔类型(bool):用来表示真或假。 2.数组和指针 数组是一组有序的数据,可以通过下标访问其中…

    C 2023年5月23日
    00
  • 详解C++句柄类

    详解C++句柄类 在C++中,句柄类是一种将资源管理委托给类实例的方法,以确保正确地释放使用的资源。本篇文章将详细讲解什么是C++句柄类,并展示了如何创建和使用句柄类。 什么是句柄类? 句柄类是一种 C++ 类,主要用于管理资源,通过封装对资源的访问来确保资源有效使用。句柄类通常用于管理底层的操作系统资源,例如文件、网络套接字、设备上下文、数据库连接等。在释…

    C 2023年5月22日
    00
  • C语言进阶之文件操作详解

    C语言进阶之文件操作详解 在C语言中,文件操作是一项非常重要的操作,涉及到了文件的创建、读写、修改、删除等各种操作。本文将针对文件操作的各个方面进行详细讲解。 文件的创建 在C语言中,文件的创建可以通过标准库函数 fopen() 来实现,其函数原型如下所示: FILE *fopen(const char *filename, const char *mode…

    C 2023年5月23日
    00
  • 从txt中读入数据到数组中(fscanf)的实现代码

    从txt中读入数据到数组中可以使用fscanf函数实现。fscanf函数的原型为: int fscanf(FILE *stream, const char *format, …); 其中第一个参数为文件流指针,第二个参数为格式字符串。后面的省略号表示待读取的参数,可以是多个。 在读取数据时,需要先打开文件,并保证文件存在,对于未找到文件的情况,需要给予提…

    C 2023年5月24日
    00
  • C语言实现病例管理系统

    C语言实现病例管理系统攻略 1. 简介 病例管理系统是医院或诊所等医疗机构常用的一种信息管理系统,通过该系统能够快速有效地管理病人的基本信息、病史以及药物处方等。这需要使用到C语言的数据类型、字符串操作等基本操作,实现起来比较简单。 2. 实现流程 2.1 确定需求 首先,我们需要明确病例管理系统需要具备哪些功能,如:添加病例、删除病例、修改病例、查询病例等…

    C 2023年5月23日
    00
  • 详解javascript对数组和json数组的操作

    下面是详解 JavaScript 对数组和 JSON 数组的操作的完整攻略。 JavaScript 数组操作 声明和初始化数组 JavaScript 中声明和初始化一个数组可以使用以下方式: // 声明空数组 var arr = []; // 声明同时初始化数组 var arr = [1, 2, 3]; // 使用 Array 构造函数声明和初始化数组 va…

    C 2023年5月23日
    00
  • 深入解析C++编程中线程池的使用

    深入解析C++编程中线程池的使用 什么是线程池? 线程池是一种用来集中处理线程的机制。线程池内包含多个线程,它们可以处理分配给线程池的任务。线程池在系统启动时就被初始化,一直运行到系统关闭。 为什么需要使用线程池? 线程池的好处是可以优化系统性能,通过重复利用已存在的线程,避免了频繁创建和销毁线程的开销。并且线程池可以缓解程序因为大量线程占用系统资源,导致系…

    C 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部