【js】js高精度加减乘除函数

加法

/**
 * 高精度加法函数,处理字符串或数字输入,去除尾部多余的零
 * @param {string|number} a - 被加数
 * @param {string|number} b - 加数
 * @returns {string} - 计算结果,去除尾部多余的零
 */
export const add = (a, b) => {
    // 将输入转换为字符串
    a = typeof a === 'number' ? a.toString() : a;
    b = typeof b === 'number' ? b.toString() : b;
    // 分割整数部分和小数部分
    let [intA = '0', decA = '0'] = a.split('.');
    let [intB = '0', decB = '0'] = b.split('.');
    // 去除小数部分可能为空的情况
    decA = decA || '0';
    decB = decB || '0';
    // 将小数部分补齐到相同长度
    const maxDecLen = Math.max(decA.length, decB.length);
    decA = decA.padEnd(maxDecLen, '0');
    decB = decB.padEnd(maxDecLen, '0');
    // 初始化进位
    let carry = 0;
    let resultDec = '';
    // 从小数部分开始逐位相加
    for (let i = maxDecLen - 1; i >= 0; i--) {
        let sum = parseInt(decA[i]) + parseInt(decB[i]) + carry;
        carry = Math.floor(sum / 10);
        resultDec = (sum % 10) + resultDec;
    }
    // 处理整数部分
    let resultInt = '';
    intA = intA.padStart(Math.max(intA.length, intB.length), '0');
    intB = intB.padStart(Math.max(intA.length, intB.length), '0');
    // 从整数部分开始逐位相加
    for (let i = intA.length - 1; i >= 0; i--) {
        let sum = parseInt(intA[i]) + parseInt(intB[i]) + carry;
        carry = Math.floor(sum / 10);
        resultInt = (sum % 10) + resultInt;
    }
    // 如果还有进位,添加到结果的开头
    if (carry) resultInt = carry + resultInt;
    // 去除结果整数部分的前导零
    resultInt = resultInt.replace(/^0+/, '');
    if (resultInt === '') resultInt = '0';
    // 拼接结果,处理小数部分尾部多余的零
    let result = resultInt + (resultDec !== '0' ? '.' + resultDec.replace(/0+$/, '') : '');
    return result;
};

减法

/**
 * 高精度减法函数,处理字符串或数字输入,去除尾部多余的零
 * @param {string|number} a - 被减数
 * @param {string|number} b - 减数
 * @returns {string} - 计算结果,去除尾部多余的零
 */
export const subtract = (a, b) => {
    // 将输入转换为字符串
    a = typeof a === 'number' ? a.toString() : a;
    b = typeof b === 'number' ? b.toString() : b;
    // 分割整数部分和小数部分
    let [intA = '0', decA = '0'] = a.split('.');
    let [intB = '0', decB = '0'] = b.split('.');
    // 去除小数部分可能为空的情况
    decA = decA || '0';
    decB = decB || '0';
    // 将小数部分补齐到相同长度
    const maxDecLen = Math.max(decA.length, decB.length);
    decA = decA.padEnd(maxDecLen, '0');
    decB = decB.padEnd(maxDecLen, '0');
    // 初始化借位
    let borrow = 0;
    let resultDec = '';
    // 从小数部分开始逐位相减
    for (let i = maxDecLen - 1; i >= 0; i--) {
        let diff = parseInt(decA[i]) - parseInt(decB[i]) - borrow;
        if (diff < 0) {
            diff += 10;
            borrow = 1;
        } else {
            borrow = 0;
        }
        resultDec = diff + resultDec;
    }
    // 处理整数部分
    let resultInt = '';
    intA = intA.padStart(Math.max(intA.length, intB.length), '0');
    intB = intB.padStart(Math.max(intA.length, intB.length), '0');
    // 从整数部分开始逐位相减
    for (let i = intA.length - 1; i >= 0; i--) {
        let diff = parseInt(intA[i]) - parseInt(intB[i]) - borrow;
        if (diff < 0) {
            diff += 10;
            borrow = 1;
        } else {
            borrow = 0;
        }
        resultInt = diff + resultInt;
    }
    // 去除结果整数部分的前导零
    resultInt = resultInt.replace(/^0+/, '');
    if (resultInt === '') resultInt = '0';
    // 拼接结果,处理小数部分尾部多余的零
    let result = resultInt + (resultDec !== '0' ? '.' + resultDec.replace(/0+$/, '') : '');
    return result;
};

乘法

/**
 * 高精度乘法函数,处理字符串或数字输入,去除尾部多余的零
 * @param {string|number} a - 乘数
 * @param {string|number} b - 被乘数
 * @returns {string} - 计算结果,去除尾部多余的零
 */
const multiply = (a, b) => {
    a = typeof a === 'number' ? a.toString() : a;
    b = typeof b === 'number' ? b.toString() : b;
    let [intA, decA] = a.split('.');
    let [intB, decB] = b.split('.');
    decA = decA || '0';
    decB = decB || '0';
    const totalDecLen = decA.length + decB.length;
    const intPartA = intA + decA;
    const intPartB = intB + decB;
    let result = Array(intPartA.length + intPartB.length).fill(0);
    for (let i = intPartA.length - 1; i >= 0; i--) {
        for (let j = intPartB.length - 1; j >= 0; j--) {
            let product = parseInt(intPartA[i]) * parseInt(intPartB[j]) + result[i + j + 1];
            result[i + j + 1] = product % 10;
            result[i + j] += Math.floor(product / 10);
        }
    }
    result = result.join('').replace(/^0+/, '');
    if (totalDecLen > 0) {
        const integerLen = result.length - totalDecLen;
        if (integerLen <= 0) {
            result = '0.' + '0'.repeat(-integerLen) + result;
        } else {
            result = result.slice(0, integerLen) + '.' + result.slice(integerLen);
        }
        result = result.replace(/(\.[0-9]*?)0+$/, '$1').replace(/\.$/, '');
    } else {
        result = result || '0';
    }
    return result;
};

除法

/**
 * 高精度除法函数,处理字符串或数字输入,去除尾部多余的零
 * @param {string|number} dividend - 被除数
 * @param {string|number} divisor - 除数
 * @param {number} precision - 结果保留的小数位数,默认为 28
 * @returns {string} - 计算结果,去除尾部多余的零
 */
export const highPrecisionDivision = (dividend, divisor, precision = 28) => {
    const dividendStr = String(dividend);
    const divisorStr = String(divisor);
    let [dividendInt = '0', dividendDec = ''] = dividendStr.split('.');
    let [divisorInt = '0', divisorDec = ''] = divisorStr.split('.');
    const maxDecLength = Math.max(dividendDec.length, divisorDec.length, precision);
    dividendDec = dividendDec.padEnd(maxDecLength, '0');
    divisorDec = divisorDec.padEnd(maxDecLength, '0');
    const dividendFull = dividendInt + '.' + dividendDec;
    const divisorFull = divisorInt + '.' + divisorDec;
    const bigDividend = parseFloat(dividendFull);
    const bigDivisor = parseFloat(divisorFull);
    let result = (bigDividend / bigDivisor).toFixed(precision);
    // 去除尾部多余的零
    result = result.replace(/\.?0+$/, '');
    return result;
};
add(0.1, "0.3") // 0.4
add(0.1, 0.3) // 0.4
add(0.1687486415614614, 0.3) // 0.4687486415614614
add("5614", "999999999999999991454444444444444444444444444444") // 999999999999999991454444444444444444444444450058


subtract("5", "3") // 2
subtract(123.45, "67.89") // 55.56
subtract('561456.514614', "679") // 560777.514614
subtract("1000000000000000000000000000000", "1") // 999999999999999999999999999999


multiply("123", "456") // 56088
multiply(0.52, "67.89") // 35.3028
multiply(0.548568482, "0.5688974989") // 0.3120792373851696698
multiply("1000000000000000000000000000000", "1") // 1000000000000000000000000000000


highPrecisionDivision(10,2) // 5
highPrecisionDivision(0.456,0.00458) // 0.1249999988609375028980608135
highPrecisionDivision('0.456',0.08) // 0.1249999988609375028980608135
highPrecisionDivision(42424,424732545354332543543) // 0.0000000000000000998840339975

在这里插入图片描述
感谢你的阅读,如对你有帮助请收藏+关注!
只分享干货实战精品从不啰嗦!!!
如某处不对请留言评论,欢迎指正~
博主可收徒、常玩QQ飞车,可一起来玩玩鸭~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/789879.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AirPods Pro新功能前瞻:iOS 18的五大创新亮点

随着科技的不断进步&#xff0c;苹果公司一直在探索如何通过创新提升用户体验。iOS 18的推出&#xff0c;不仅仅是iPhone的一次系统更新&#xff0c;更是苹果生态链中重要一环——AirPods Pro的一次重大升级。 据悉&#xff0c;iOS 18将为AirPods Pro带来五项新功能&#xff0…

985研究生8年终毕业,学位证颁发11天后被作废?

“正常是学校颁证给学院&#xff0c;但学院就没告诉我&#xff0c;还把学校颁发的证书给撤销了&#xff0c;这中间学院并没有书面或电话告知我本人。”34岁读研&#xff0c;如今已42岁的内蒙古任女士回想起求学不易&#xff0c;很是心酸。 2015年3月&#xff0c;任女士考取2015…

昇思25天学习打卡营第12天|Vision Transformer图像分类

关于Vision Transformer Vision Transformer&#xff08;ViT&#xff09;结构和工作原理 ViT模型的主体结构是基于Transformer模型的Encoder部分 图像分块&#xff1a;ViT首先将输入图像分割成一系列固定大小的patch&#xff08;例如16x16像素&#xff09;。然后&#xff0c;…

【正点原子i.MX93开发板试用连载体验】简单的音频分类

本文最早发表于电子发烧友论坛&#xff1a; 今天测试的内容是进行简单的音频分类。我们要想进行语音控制&#xff0c;就需要构建和训练一个基本的自动语音识别 (ASR) 模型来识别不同的单词。如果想了解这方面的知识可以参考TensorFlow的官方文档&#xff1a;简单的音频识别&…

在2018.3没有找到对应的器件库,需要

图中的器件在vivado中没有找到 一、添加器件 发现所有的2018.3的所有器件库&#xff0c;其实都已经安装了&#xff0c;那么意味着2018.3没有办法对该器件进行综合。 二、安装更新版本的vivado 重新安装的2022.2&#xff0c;在选择器件的时候&#xff0c;把所有的器件全部勾选…

Quartus程序烧录

1. .sof文件烧录&#xff08;断电丢失&#xff09; &#xff08;1&#xff09;Programmer&#xff08;程序设计&#xff09; &#xff08;2&#xff09;Hardware Setup...&#xff08;硬件设置&#xff09; &#xff08;如无USB-Blaster[USB-0]&#xff0c;在Hardware Setup..…

TCP 握手数据流

这张图详细描述了 TCP 握手过程中&#xff0c;从客户端发送 SYN 包到服务器最终建立连接的整个数据流转过程&#xff0c;包括网卡、内核、进程中的各个环节。下面对每个步骤进行详细解释&#xff1a; 客户端到服务器的初始连接请求 客户端发送 SYN 包&#xff1a; 客户端发起…

wmv如何转为mp4格式?推荐几个将wmv转换成MP4的方法

wmv如何转为mp4格式&#xff1f;在当今数字化和多媒体内容分享的时代&#xff0c;视频格式的转换变得至关重要。wmv作为一种常见的视频格式&#xff0c;在Windows系统中有较好的兼容性&#xff0c;但实际上存在多项严重问题。更为不利的是&#xff0c;由于wmv属于比较新的视频类…

制作一个自动养号插件的必备源代码!

随着网络社交平台的日益繁荣&#xff0c;用户对于账号的维护和运营需求也日益增长&#xff0c;在这样的背景下&#xff0c;自动养号插件应运而生&#xff0c;成为了许多用户提升账号活跃度、增加曝光量的得力助手。 然而&#xff0c;制作一个高效、稳定的自动养号插件并非易事…

AMD X3D CPU 史诗级进化,锐龙7 9800X3D默秒全

6 月份刚刚结束&#xff0c;这有关下半年新一代 PC 硬件消息便愈发蠢蠢欲动起来。 上个月初台北国际电脑展上&#xff0c;AMD 正式公布了下一代 Zen 5 架构 Ryzen 9000 系列桌面处理器。 AMD 前脚刚大吹特吹性能吊锤 Intel i9 14900K 云云&#xff0c;没想到反手又来了一波被自…

飞腾平台虚拟机组播性能调优指南

【写在前面】 飞腾开发者平台是基于飞腾自身强大的技术基础和开放能力&#xff0c;聚合行业内优秀资源而打造的。该平台覆盖了操作系统、算法、数据库、安全、平台工具、虚拟化、存储、网络、固件等多个前沿技术领域&#xff0c;包含了应用使能套件、软件仓库、软件支持、软件适…

【45 Pandas+Pyecharts | 去哪儿海南旅游攻略数据分析可视化】

文章目录 &#x1f3f3;️‍&#x1f308; 1. 导入模块&#x1f3f3;️‍&#x1f308; 2. Pandas数据处理2.1 读取数据2.2 查看数据信息2.3 日期处理&#xff0c;提取年份、月份2.4 经费处理2.5 天数处理 &#x1f3f3;️‍&#x1f308; 3. Pyecharts数据可视化3.1 出发日期_…

Vatee万腾平台:智慧生活的无限可能

在科技日新月异的今天&#xff0c;我们的生活正被各种智能技术悄然改变。从智能家居到智慧城市&#xff0c;从个人健康管理到企业数字化转型&#xff0c;科技的力量正以前所未有的速度渗透到我们生活的每一个角落。而在这场智能革命的浪潮中&#xff0c;Vatee万腾平台以其卓越的…

【想要了解Anaconda介绍、安装配置及使用,看这篇文章就够了】

一、Anaconda介绍及安装配置 1、Anaconda简介 Anaconda是一个用于科学计算的 Python 发行版&#xff0c;支持 Linux, Mac, Windows, 包含conda、Python等190多个科学包及其依赖项。它便于获取和管理包&#xff0c;包括python和许多常用软件库&#xff08;如numpy、pandas等&a…

数据库基础练习4

准备 create table dept (dept1 int ,dept_name varchar(11)) charsetutf8; create table emp (sid int ,name varchar(11),age int,worktime_start date,incoming int,dept2 int) charsetutf8;insert into dept values(101,财务),(102,销售),(103,IT技术),(104,行政);INSERT …

如何分辨AI生成的内容?AI生成内容检测工具对比实验

检测人工智能生成的文本对各个领域的组织都提出了挑战&#xff0c;包括学术界和新闻界等。生成式AI与大语言模型根据短描述来进行内容生成的能力&#xff0c;产生了一个问题&#xff1a;这篇文章/内容/作业/图像到底是由人类创作的&#xff0c;还是AI创作的&#xff1f;虽然 LL…

前端面试题(CSS篇六)

一、浏览器如何判断是否支持 webp 格式图片 &#xff08;1&#xff09;宽高判断法。通过创建image对象&#xff0c;将其src属性设置为webp格式的图片&#xff0c;然后在onload事件中获取图片的宽高&#xff0c;如果能够获取&#xff0c;则说明浏览器支持webp格式图片。如果不能…

随身WiFi市场乱象横生,随身WiFi测评最好的格行随身WiFi如何引领变革?

在当今随身WiFi市场乱象频发、内卷严重的背景下&#xff0c;消费者对于产品的性能与商家是否会后台割韭菜依旧存疑&#xff0c;尤其是“随身WiFi到底卡不卡&#xff1f;”的问题&#xff0c;成为了广大消费者关注的重点。然而&#xff0c;在众多品牌中&#xff0c;格行随身WiFi…

DSVPN综合实验(NHRP之shortcut模式,证书认证模式)

一、实验目的 通过NAT设备将内网地址映射至外网&#xff0c;在站点间构建VPN隧道&#xff0c;认证方式分别使用预配置密码和证书两种方式实现 二、基础配置 &#xff08;一&#xff09;如图所示配置接口地址&#xff0c;在R1上将FW1地址映射至外网 [R1-GigabitEthernet0/0/1…

Geoserver源码解读六 插件

系列文章目录 Geoserver源码解读一 环境搭建 Geoserver源码解读二 主入口 Geoserver源码解读三 GeoServerBasePage Geoserver源码解读四 REST服务 Geoserver源码解读五 Catalog Geoserver源码解读六 插件&#xff08;怎么在开发模式下使用&#xff09; 目录 系列文章目…