详解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日

相关文章

  • C语言中如何进行GUI编程?

    要在C语言中进行GUI编程,需要使用专门的库或框架。以下是两种常用的GUI编程方式: 1. 使用GTK+库进行GUI编程 GTK+是一个跨平台的开源GUI库,它基于C语言编写。使用GTK+编写GUI程序的基本步骤如下: 步骤一:安装GTK+库 在Ubuntu系统下,可以输入以下命令安装GTK+库: sudo apt-get install libgtk2.0…

    C 2023年4月27日
    00
  • C++11之std::future对象的使用以及说明

    C++11中的std::future对象是一种异步编程的工具,可以让我们更加方便地进行异步操作。在本文中,我们将详细讲解如何使用std::future对象以及它的几个重要特点。 什么是std::future对象? std::future是C++11中的异步编程工具之一,是表示异步操作结果的一个类模板。当我们进行异步操作时,可以使用std::future来获取…

    C 2023年5月22日
    00
  • Visual Studio 2022 的安装和创建C++项目(图文教程)

    下面是详细讲解 Visual Studio 2022 的安装和创建 C++ 项目的攻略: 1.下载和安装 Visual Studio 2022 首先,我们需要下载并安装 Visual Studio 2022。可以在微软官网上下载安装包,具体流程如下: 1.1 访问 Visual Studio 官网 首先,在浏览器中访问 Visual Studio 官网。 1…

    C 2023年5月30日
    00
  • .NET Core Dapper操作mysql数据库的实现方法

    让我来详细讲解“.NET Core Dapper操作mysql数据库的实现方法”的完整攻略。 步骤一:配置远程连接MySQL数据库 要使用Dapper操作MySQL数据库,首先需要配置远程连接MySQL数据库。在Visual Studio中创建.NET Core项目后,需要修改appsettings.json文件,将其修改为以下格式: { "Con…

    C 2023年5月23日
    00
  • golang使用json格式实现增删查改的实现示例

    下面我将详细讲解一下使用 Golang 中的 json 包实现增删查改的实现示例。 增删查改简介 增删查改是非常基本的 CRUD 操作,即创建(Create)、读取(Retrieve)、更新(Update)和删除(Delete)。在 web 应用开发中,这些操作是必不可少的,而 json 格式是 web 应用开发中经常用到的数据格式。 在 Golang 中,…

    C 2023年5月23日
    00
  • 深入N皇后问题的两个最高效算法的详解

    让我来详细讲解一下“深入N皇后问题的两个最高效算法的详解”。 算法一:位运算 算法思路 基于位运算的 N 皇后问题算法,是一种高效的算法。其核心思路在于将每行、每列、每条对角线(包括左上角至右下角、右上角至左下角)都用一个二进制数来表示,通过位运算的方式来判断该位置是否可以放皇后。 其中,用两个 int 类型的变量 col 和 ld 来表示列和左对角线(左上…

    C 2023年5月22日
    00
  • 原生js调用json方法总结

    当我们需要使用JSON格式的数据时,使用JavaScript原生的JSON API来处理数据是非常常见的。在本篇文档中,我们将会全面介绍如何原生JS调用JSON方法。 JSON简介 JSON (JavaScript对象表示法) 是一种用于将数据存储和交换的文本格式。JSON 派生自JavaScript语言,但是JSON 格式是语言无关的。 JSON是一种非常…

    C 2023年5月23日
    00
  • 详解几十行代码实现一个vue的状态管理

    下面我将详细讲解如何实现一个vue的状态管理。 1. 状态管理器的作用 在使用Vue进行大型前端应用开发时,随着组件数量的增加,组件之间的状态共享也变得越来越复杂。这时候就需要一个或多个状态管理器来维护应用的整体状态,使得组件间的状态共享变得更加灵活、稳定。 2. 状态管理器的实现 一个简单的vue状态管理器有以下几个基本要素: 2.1. 状态(state)…

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