C#,《小白学程序》第二十七课:大数四则运算之“运算符重载”的算法及源程序

2023-11-01

1 文本格式

using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;

/// <summary>
/// 大数的四则(加减乘除)运算
/// 及其运算符重载(取余数)
/// </summary>
public class BigNumber
{
    private string Buffer { get; set; } = "";
    private string Sign { get; set; } = "";
    public BigNumber(int n) { Next(n); }
    public BigNumber(string b, string s = "")
    {
        Buffer = b;
        Sign = s;
    }
    public BigNumber Clone()
    {
        BigNumber r = new BigNumber(Buffer, Sign);
        return r;
    }
    public int Length { get { return Buffer.Length; } }

    /// <summary>
    /// 随机生成任意长度的大数(BigNumber)
    /// </summary>
    /// <param name="n">位数</param>
    /// <returns></returns>
    public void Next(int n)
    {
        Random rnd = new Random();
        StringBuilder sb = new StringBuilder();
        sb.Append((rnd.Next(9) + 1).ToString());
        for (int i = 1; i < n; i++)
        {
            sb.Append((rnd.Next(10)).ToString());
        }
        Buffer = sb.ToString();
    }

    /// <summary>
    /// 字符串型的数字转为数组(低位(右)在前)
    /// </summary>
    /// <param name="a"></param>
    /// <param name="n">最大位数,后面留0</param>
    /// <returns></returns>
    public static int[] string_to_digitals(string a, int n)
    {
        char[] c = a.ToCharArray();
        int[] d = new int[n];
        for (int i = a.Length - 1, j = 0; i >= 0; i--)
        {
            if (c[i] == '-') continue;
            d[j++] = c[i] - '0';
        }
        return d;
    }

    /// <summary>
    /// 数组型数字转为字符串型(低位(右)在前)
    /// </summary>
    /// <param name="d"></param>
    /// <returns></returns>
    public static string digitals_to_string(int[] d)
    {
        int n = d.Length;
        int k = n - 1;
        while ((k >= 0) && (d[k] == 0)) k--;
        if (k >= 0)
        {
            StringBuilder sb = new StringBuilder();
            for (; k >= 0; k--) sb.Append(d[k]);
            return sb.ToString();
        }
        else
        {
            return "0";
        }
    }

    /// <summary>
    /// 大数加法 c = a + b
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>
    public static string big_integer_plus(string a, string b)
    {
        int n = Math.Max(a.Length, b.Length) + 1;
        // 位数不长的数字直接计算
        if (n <= 18)
        {
            return (ulong.Parse(a) + ulong.Parse(b)).ToString();
        }

        int[] da = string_to_digitals(a, n);
        int[] db = string_to_digitals(b, n);

        int[] dc = new int[n];
        Array.Copy(da, dc, n);
        for (int i = 0; i < (n - 1); i++)
        {
            dc[i] = dc[i] + db[i];
            if (dc[i] > 9)
            {
                dc[i] -= 10;
                dc[i + 1] += 1;
            }
        }
        return digitals_to_string(dc);
    }

    /// <summary>
    /// 大数减法 c = a - b
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>
    public static string big_integer_subtract(string a, string b)
    {
        int na = a.Length;
        int nb = b.Length;
        int n = Math.Max(na, nb) + 1;
        if (n <= 18)
        {
            return (ulong.Parse(a) - ulong.Parse(b)).ToString();
        }
        int[] da = string_to_digitals(a, n);
        int[] db = string_to_digitals(b, n);

        for (int i = 0; i < na; i++)
        {
            da[i] -= db[i];
            if (da[i] < 0)
            {
                da[i] += 10;
                da[i + 1] -= 1;
            }
        }
        return digitals_to_string(da);
    }

    /// <summary>
    /// 大数乘法 c = a * b
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>
    public static string big_integer_multiply(string a, string b)
    {
        int na = a.Length;
        int nb = b.Length;
        int n = na + nb + 1;
        int[] da = string_to_digitals(a, n);
        int[] db = string_to_digitals(b, n);

        int[] dc = new int[n];
        for (int i = 0; i < na; i++)
        {
            for (int j = 0; j < nb; j++)
            {
                dc[i + j] += da[i] * db[j];
            }
        }
        for (int i = 0; i < n; i++)
        {
            if (dc[i] >= 10)
            {
                dc[i + 1] += (dc[i] / 10);
                dc[i] %= 10;
            }
        }

        return digitals_to_string(dc);
    }

    /// <summary>
    /// 比较a,b的大小,返回1,0,-1
    /// 数据从低位(右)往高位(左)存储;
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>
    public static int big_integer_compare(int[] a, int[] b)
    {
        for (int i = a.Length - 1; i >= 0; i--)
        {
            if (a[i] > b[i]) return 1;
            else if (a[i] < b[i]) return -1;
        }
        return 0;
    }

    public static int big_integer_compare(string a, string b)
    {
        int n = Math.Max(a.Length, b.Length);
        int[] da = string_to_digitals(a, n);
        int[] db = string_to_digitals(a, n);
        return big_integer_compare(da, db);
    }

    /// <summary>
    /// 大数除法 c = a / b % d
    /// c 为商,d 为余数。
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <param name="d">余数</param>
    /// <returns>商c</returns>
    public static string big_integer_divide(string a, string b, out string d)
    {
        int n = a.Length;
        int[] db = string_to_digitals(b, n);

        string q = a;
        List<string> p = new List<string>();
        int[] dq = string_to_digitals(q, n);
        while (big_integer_compare(dq, db) >= 0)
        {
            int len = q.Length - b.Length;
            string v2 = b + String.Join("", new int[len]);
            int[] dv = string_to_digitals(v2, n);
            if (big_integer_compare(dq, dv) < 0)
            {
                len--;
                v2 = b + String.Join("", new int[len]);
                dv = string_to_digitals(v2, n);
            }

            string v1 = "1" + String.Join("", new int[len]);
            while (big_integer_compare(dq, dv) >= 0)
            {
                p.Add(v1);
                q = big_integer_subtract(q, v2);
                dq = string_to_digitals(q, n);
            }
        }

        d = q;

        string r = p[0];
        for (int i = 1; i < p.Count; i++)
        {
            r = big_integer_plus(r, p[i]);
        }
        return r;
    }

    #region 四则运算符(含取余数)重载

    // 运算符重载是一种常用的编程技术。
    // 用于支持“非数值类型的数据(比如类)”以常用的运算符 +-*/% 等等进行运算,使得代码简约直观。
    // 没有运算符重载的语言(比如golang)一般都不适合数值计算。

    public static BigNumber operator +(BigNumber a, BigNumber b)
    {
        return new BigNumber(big_integer_plus(a.Buffer, b.Buffer));
    }
    public static BigNumber operator -(BigNumber a, BigNumber b)
    {
        if (a > b || a == b)
            return new BigNumber(big_integer_subtract(a.Buffer, b.Buffer));
        else
            return new BigNumber(big_integer_subtract(b.Buffer, a.Buffer), "-");
    }
    public static BigNumber operator *(BigNumber a, BigNumber b)
    {
        return new BigNumber(big_integer_multiply(a.Buffer, b.Buffer));
    }
    public static BigNumber operator /(BigNumber a, BigNumber b)
    {
        return new BigNumber(big_integer_divide(a.Buffer, b.Buffer, out string _));
    }
    public static BigNumber operator %(BigNumber a, BigNumber b)
    {
        string c = big_integer_divide(a.Buffer, b.Buffer, out string d);
        return new BigNumber(d);
    }
    public static bool operator >(BigNumber a, BigNumber b)
    {
        return big_integer_compare(a.Buffer, b.Buffer) > 0;
    }
    public static bool operator <(BigNumber a, BigNumber b)
    {
        return big_integer_compare(a.Buffer, b.Buffer) < 0;
    }
    public static bool operator ==(BigNumber a, BigNumber b)
    {
        return big_integer_compare(a.Buffer, b.Buffer) == 0;
    }
    public static bool operator !=(BigNumber a, BigNumber b)
    {
        return big_integer_compare(a.Buffer, b.Buffer) != 0;
    }
    public static bool Equals(BigNumber a, BigNumber b) { return (a == b); }

    public override string ToString()
    {
        return Sign + Buffer;
    }
    #endregion
}
 

2 代码格式

using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;

/// <summary>
/// 大数的四则(加减乘除)运算
/// 及其运算符重载(取余数)
/// </summary>
public class BigNumber
{
    private string Buffer { get; set; } = "";
    private string Sign { get; set; } = "";
    public BigNumber(int n) { Next(n); }
    public BigNumber(string b, string s = "")
    {
        Buffer = b;
        Sign = s;
    }
    public BigNumber Clone()
    {
        BigNumber r = new BigNumber(Buffer, Sign);
        return r;
    }
    public int Length { get { return Buffer.Length; } }

    /// <summary>
    /// 随机生成任意长度的大数(BigNumber)
    /// </summary>
    /// <param name="n">位数</param>
    /// <returns></returns>
    public void Next(int n)
    {
        Random rnd = new Random();
        StringBuilder sb = new StringBuilder();
        sb.Append((rnd.Next(9) + 1).ToString());
        for (int i = 1; i < n; i++)
        {
            sb.Append((rnd.Next(10)).ToString());
        }
        Buffer = sb.ToString();
    }

    /// <summary>
    /// 字符串型的数字转为数组(低位(右)在前)
    /// </summary>
    /// <param name="a"></param>
    /// <param name="n">最大位数,后面留0</param>
    /// <returns></returns>
    public static int[] string_to_digitals(string a, int n)
    {
        char[] c = a.ToCharArray();
        int[] d = new int[n];
        for (int i = a.Length - 1, j = 0; i >= 0; i--)
        {
            if (c[i] == '-') continue;
            d[j++] = c[i] - '0';
        }
        return d;
    }

    /// <summary>
    /// 数组型数字转为字符串型(低位(右)在前)
    /// </summary>
    /// <param name="d"></param>
    /// <returns></returns>
    public static string digitals_to_string(int[] d)
    {
        int n = d.Length;
        int k = n - 1;
        while ((k >= 0) && (d[k] == 0)) k--;
        if (k >= 0)
        {
            StringBuilder sb = new StringBuilder();
            for (; k >= 0; k--) sb.Append(d[k]);
            return sb.ToString();
        }
        else
        {
            return "0";
        }
    }

    /// <summary>
    /// 大数加法 c = a + b
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>
    public static string big_integer_plus(string a, string b)
    {
        int n = Math.Max(a.Length, b.Length) + 1;
        // 位数不长的数字直接计算
        if (n <= 18)
        {
            return (ulong.Parse(a) + ulong.Parse(b)).ToString();
        }

        int[] da = string_to_digitals(a, n);
        int[] db = string_to_digitals(b, n);

        int[] dc = new int[n];
        Array.Copy(da, dc, n);
        for (int i = 0; i < (n - 1); i++)
        {
            dc[i] = dc[i] + db[i];
            if (dc[i] > 9)
            {
                dc[i] -= 10;
                dc[i + 1] += 1;
            }
        }
        return digitals_to_string(dc);
    }

    /// <summary>
    /// 大数减法 c = a - b
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>
    public static string big_integer_subtract(string a, string b)
    {
        int na = a.Length;
        int nb = b.Length;
        int n = Math.Max(na, nb) + 1;
        if (n <= 18)
        {
            return (ulong.Parse(a) - ulong.Parse(b)).ToString();
        }
        int[] da = string_to_digitals(a, n);
        int[] db = string_to_digitals(b, n);

        for (int i = 0; i < na; i++)
        {
            da[i] -= db[i];
            if (da[i] < 0)
            {
                da[i] += 10;
                da[i + 1] -= 1;
            }
        }
        return digitals_to_string(da);
    }

    /// <summary>
    /// 大数乘法 c = a * b
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>
    public static string big_integer_multiply(string a, string b)
    {
        int na = a.Length;
        int nb = b.Length;
        int n = na + nb + 1;
        int[] da = string_to_digitals(a, n);
        int[] db = string_to_digitals(b, n);

        int[] dc = new int[n];
        for (int i = 0; i < na; i++)
        {
            for (int j = 0; j < nb; j++)
            {
                dc[i + j] += da[i] * db[j];
            }
        }
        for (int i = 0; i < n; i++)
        {
            if (dc[i] >= 10)
            {
                dc[i + 1] += (dc[i] / 10);
                dc[i] %= 10;
            }
        }

        return digitals_to_string(dc);
    }

    /// <summary>
    /// 比较a,b的大小,返回1,0,-1
    /// 数据从低位(右)往高位(左)存储;
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>
    public static int big_integer_compare(int[] a, int[] b)
    {
        for (int i = a.Length - 1; i >= 0; i--)
        {
            if (a[i] > b[i]) return 1;
            else if (a[i] < b[i]) return -1;
        }
        return 0;
    }

    public static int big_integer_compare(string a, string b)
    {
        int n = Math.Max(a.Length, b.Length);
        int[] da = string_to_digitals(a, n);
        int[] db = string_to_digitals(a, n);
        return big_integer_compare(da, db);
    }

    /// <summary>
    /// 大数除法 c = a / b % d
    /// c 为商,d 为余数。
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <param name="d">余数</param>
    /// <returns>商c</returns>
    public static string big_integer_divide(string a, string b, out string d)
    {
        int n = a.Length;
        int[] db = string_to_digitals(b, n);

        string q = a;
        List<string> p = new List<string>();
        int[] dq = string_to_digitals(q, n);
        while (big_integer_compare(dq, db) >= 0)
        {
            int len = q.Length - b.Length;
            string v2 = b + String.Join("", new int[len]);
            int[] dv = string_to_digitals(v2, n);
            if (big_integer_compare(dq, dv) < 0)
            {
                len--;
                v2 = b + String.Join("", new int[len]);
                dv = string_to_digitals(v2, n);
            }

            string v1 = "1" + String.Join("", new int[len]);
            while (big_integer_compare(dq, dv) >= 0)
            {
                p.Add(v1);
                q = big_integer_subtract(q, v2);
                dq = string_to_digitals(q, n);
            }
        }

        d = q;

        string r = p[0];
        for (int i = 1; i < p.Count; i++)
        {
            r = big_integer_plus(r, p[i]);
        }
        return r;
    }

    #region 四则运算符(含取余数)重载

    // 运算符重载是一种常用的编程技术。
    // 用于支持“非数值类型的数据(比如类)”以常用的运算符 +-*/% 等等进行运算,使得代码简约直观。
    // 没有运算符重载的语言(比如golang)一般都不适合数值计算。

    public static BigNumber operator +(BigNumber a, BigNumber b)
    {
        return new BigNumber(big_integer_plus(a.Buffer, b.Buffer));
    }
    public static BigNumber operator -(BigNumber a, BigNumber b)
    {
        if (a > b || a == b)
            return new BigNumber(big_integer_subtract(a.Buffer, b.Buffer));
        else
            return new BigNumber(big_integer_subtract(b.Buffer, a.Buffer), "-");
    }
    public static BigNumber operator *(BigNumber a, BigNumber b)
    {
        return new BigNumber(big_integer_multiply(a.Buffer, b.Buffer));
    }
    public static BigNumber operator /(BigNumber a, BigNumber b)
    {
        return new BigNumber(big_integer_divide(a.Buffer, b.Buffer, out string _));
    }
    public static BigNumber operator %(BigNumber a, BigNumber b)
    {
        string c = big_integer_divide(a.Buffer, b.Buffer, out string d);
        return new BigNumber(d);
    }
    public static bool operator >(BigNumber a, BigNumber b)
    {
        return big_integer_compare(a.Buffer, b.Buffer) > 0;
    }
    public static bool operator <(BigNumber a, BigNumber b)
    {
        return big_integer_compare(a.Buffer, b.Buffer) < 0;
    }
    public static bool operator ==(BigNumber a, BigNumber b)
    {
        return big_integer_compare(a.Buffer, b.Buffer) == 0;
    }
    public static bool operator !=(BigNumber a, BigNumber b)
    {
        return big_integer_compare(a.Buffer, b.Buffer) != 0;
    }
    public static bool Equals(BigNumber a, BigNumber b) { return (a == b); }

    public override string ToString()
    {
        return Sign + Buffer;
    }
    #endregion
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C#,《小白学程序》第二十七课:大数四则运算之“运算符重载”的算法及源程序 的相关文章

随机推荐

  • 使用OpenAPIKey来调用ChatGPT并解决生成回答控制台显示不全的问题

    使用OpenAPIKey来调用ChatGPT并解决生成回答控制台显示不全的问题 Code import os import openai import re def get ai response prompt engine text da
  • react-lazyload懒加载控件源码解析

    简介 本篇文章主要介绍一个优秀的基于react实现的懒加载控件 github com twobin reac 优点 易于使用 比如
  • 基于机器学习的心脏成像诊断

    心脏成像在心血管疾病 CVD 的诊断中起着重要作用 但到目前为止 它的作用仅限于对心脏结构和功能的观察和定量评估 然而 随着大数据和机器学习的出现 人工智能方法的出现将直接帮助临床医生诊断CVD 本文全面回顾了这一领域的最新研究成果 并为读
  • js数组去重常用方法

    js数组去重是面试中经常会碰到的问题 无论是前端还是node js数组常见的有两种形式 一种是数组各元素均为基本数据类型 常见的为数组字符串格式 形如 a b c 一种是数组各元素不定 元素中既有基本数据类型 也有引用数据类型 形式如 na
  • 某书最新版X-s(2023/5/23更新)

    前不久刚写过xhs的x s 前几天听一些小伙伴说又更新了 我二话不说还按原先的逆向思路 直接搜function sign 开始施展补环境大法 一顿无用的折腾 补完后 测试发现死活不成功 这真是离了大谱了 对比了一下 通过补环境 sign生成
  • 【linux】【tar】tar命令详解之czvf,xzvf

    Linux tar 英文全拼 tape archive 命令主要用于文件的打包压缩及解压 命令最初的设计目的是为了将文件备份到磁带上 tapearchive 因而得名tar 1 常用tar命令实例 打包命令 tar czvf xxx 说明
  • 代码布局优化

    代码布局优化是编译技术中的一种策略 其目的是调整程序中函数和数据的物理布局 以提高程序的执行速度 更好的代码布局能够有效利用现代处理器的特性 例如指令缓存和分支预测 从而提高性能 以下是代码布局优化的几个关键方面 指令缓存效率 当处理器执行
  • linux系统支持ntfs吗,Linux支持NTFS格式文件的方法

    一般情况下Linux系统是不支持NTFS文件系统的 所以我们不能在Linux系统中挂载NTFS文件系统类型的硬盘或移动硬盘 那么我们如何才能让Linux系统支持NTFS文件系统呢 现在我们去看看Linux支持NTFS格式文件的方法介绍 Li
  • VS 2022(Visual Studio 2022)菜单栏中增加文件-高级保存选项

    背景 最近想使用VS工具来开发Qt项目 但运行后发现程序运行中文会显示乱码 在网上找了相关资料后需要使用高级保存选项来更改文件编码为UTF 8类型 但VS2022貌似没有高级保存选项 摸索一番后发现添加该选项的方法 故而分享一下 参考连接
  • iwebsec靶场 文件包含漏洞通关笔记8-php://input伪协议利用

    目录 前言 1 php input伪协议原理 2 php input伪协议使用条件 第08关 php input伪协议利用 1 打开靶场 2 源码分析 3 伪协议渗透获取php信息 1 构造post信息 2 渗透 4 伪协议获取目录信息 1
  • 基础指针【指针的基本使用方法和注意事项】

    基础指针目录 前言 指针 指针是什么 指针的大小 指针的定义和赋值 指针的使用 传值调用和传址调用 传值调用 传址调用 指针的弊端 野指针 使用指针的注意事项 前言 指针 是我们在学习C语言中的一个重难点 关乎到我们学习C语言的深度和理解
  • module.exports、exports、export default、export、require、import

    在es5中 用 module exports 和 exports 导出模块 用 require 导入模块 在es6中 新增 export default 和 export 导出模块 用 import 导入模块 一般的 module expo
  • java 设置不缓存,java – 禁用通过外部属性的spring方法缓存

    我使用ehcache和注释驱动配置配置了 spring方法缓存 但是 我希望能够从我们在应用程序中使用的配置文件中禁用它 我的第一个想法是如果禁用方法缓存 则调用net sf ehcache CacheManager CacheManage
  • Vue3中的hook

    一 hook的基本使用 Vue3中的hook通常被称为Composition API 是Vue js框架中的一个重要特性 它们的本质是一些可以在组件内部使用的函数 这些函数能够让你在不影响组件逻辑的情况下 增强和扩展组件的功能 Hook的主
  • VS2015:当前不会命中断点,显示当前不会命中断点 没有与此行关联的可执行代码

    使用VS在Release模式下打断点进行调试 有时候不会命中断点 显示信息如下 当前不会命中断点 显示当前不会命中断点 没有与此行关联的可执行代码 这是因为Release模式下 编译器进行编译优化时 忽略掉了这个断点 为此需要 releas
  • ERROR: You must give at least one requirement to install (see "pip help install")

    使用pip install 命令时遇到You must give at least one requirement to install see pip help install 原因是install 后面没有参数 也就是说没有给想要安装的
  • 蓝牙AOA高精度定位

    01 蓝牙AOA定位技术原理 2019 年初 蓝牙技大联盟宣布蓝牙 5 1 引入了新的 寻向 功能 这个功能可检测蓝牙信号的方向 将大幅提高蓝牙定位的精确度 提供更好的位置服务 结束了以往通过 RSSI 信号强度的方式做低精度指纹定位的历史
  • qt程序设置同时只能运行一个,避免重复打开

    qt程序设置同时只能运行一个 避免重复打开 1 qt程序设置同时只能运行一个 避免重复打开 2 Qt 桌面软件防止重新启动 一 创建互斥量 二 使用QLockFile 创建锁定文件 通过能否锁定来判断是否已经有程序启动 三 使用 系统信号量
  • too few arguments

    改为 解决
  • C#,《小白学程序》第二十七课:大数四则运算之“运算符重载”的算法及源程序

    1 文本格式 using System using System Text using System Collections using System Collections Generic