IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> JAVASCRIPT遇到《九章算术》-卷第一 方田 (2)约分 -> 正文阅读

[JavaScript知识库]JAVASCRIPT遇到《九章算术》-卷第一 方田 (2)约分

本章节对应视频

原文:

今有十八分之十二。问约之得几何?

答曰:三分之二。

又有九十一分之四十九。问约之得几何?

答曰:十三分之七。

约分

【按约分者,物之数量,不可悉全,必以分言之。分之为数,繁则难用。设有四分之二者,繁而言之,亦可为八分之四;约而言之,则二分之一也。虽则异辞,至于为数,亦同归尔。法实相推,动有参差,故为术者先治诸分。】

术曰:可半者半之。不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。

【等数约之,即除也。其所以相减者,皆等数之重叠,故以等数约之。】

“约分”简单来定义,就是通过计算使一个分数的分子、分母不存在除1以外的公约数。

把约分术提到的方法,按步骤梳理出来,就是:

1、分子、分母都是偶数的,同时除以2,重复这个步骤,直到分子、分母出现奇数;

2、分子、分母中存在奇数时,用其中较大的数减较小的数;

3、用上一步得出的差和上一步的减数进行比较,用其中较大的数减较小的数;

4、重复步骤3,直到减数与差相等;

5、用步骤2中的分子、分母同时除以步骤4中最终得到的差,得到约分的结果。

这是我们遇到的第一个计算过程逻辑比较复杂的问题,用表达式来描述这个过程不太合适,可以用伪代码来描述。

伪代码:

约分(分子/分母){
    while(分子、分母都为偶数){
        分子/2,分母/2
    }
    if(分子、分母包含奇数){
        较小值 = 分子、分母中较小的数
        差值 = (分母-分子)绝对值
        while(较小值!=差值){
             新较小值 = 较小值、差值中较小的数
            新差值 = (较小值-差值)绝对值
            if(新较小值 = 新差值){
                公约数 = 新较小值
                跳出循环
             }
             较小值 = 新较小值
             差值 = 新差值
        }
        分子 = 分子/公约数
        分母 = 分母/公约数 
    }   
    return 分子/分母
}

接下来用实际的代码来实现这个功能。

编程语言中原生数据类型没有分数这个数据类型,我们可以创建一个用于表示分数的类或结构体,然后以这个分数类作为输入输出的类型;更简单粗暴的方式是直接把分子、分母作为两个整型数据作为传入参数和返回值。

我这里以包含分子、分母两个字段的json作为参数,本质就是第二种方式。

针对错误输入和特殊输入,需要进行处理。

输入中包含分子、分母的数值,所以需要判断分母不能为0。(强类型语言形参会筛选传入参数类型,不需要单独判断是否是整数,这里就先不筛选输入是否是整数了。)分子为0时,约分结果也是0;分子等于分母时,约分结果为1。

另外,原文的计算方法没有考虑负数,我们需要考虑对于输入负分数做处理。为了应对负分数作为参数的情况,可以在分子、分母存在奇数时求最大公约数的运算中,取绝对值进行计算,这样就不会受正负数的影响。(正负数不会影响同时除以2的操作,所以分子、分母都是偶数时,不用考虑这个问题。)前面特殊输入判定“分子等于分母”,也需要改变为“分子、分母绝对值相等”,相应处理改??为返回“分子/分母”,就是包含正负号的1。

需要代码源文件的小伙伴可以关注我的微信公众号: JianMing-95

输入:{分子,分母}

输出:{约分后的分子,约分后的分母}

基础版代码:

function chOne02(input){ //以json格式输入:分子num,分母den
    let num = input.num;
    let den = input.den;
    if(den === 0){ //筛选输入,分母不能为0
        return {"code":"001","msg":"分母不能为0,请重新输入!"};
    }
    if(num === 0){ //分子为0时,直接返回结果0
        return{"res":0};
    }
    if(Math.abs(num) === Math.abs(den)){ //分子分母绝对值相等时,直接返回结果 分子/分母(带符号的1)
        return{"res":num/den};
    }
    while(num % 2 === 0 && den % 2 === 0){ //分子、分母都是偶数时,除以2
        num = num / 2;
        den = den / 2;
    }   
    if(num % 2 !=0 || den % 2 != 0){//分子、分母包含奇数时执行下面操作
        let min = Math.abs(num) < Math.abs(den) ? Math.abs(num) : Math.abs(den); //取分子、分母中绝对值较小值储存在min中
        let dif = Math.abs(Math.abs(num) - Math.abs(den)); //计算分子、分母相减所得差的绝对值
        let divisor; //声明一个最大公约数变量divisor
        while(min != dif){ //上次减法的差和减数不相等时重复下面操作
            let newMin = min < dif ? min : dif; //把上次减法的减数和差中较小值存储在newMin中
            let newDif = Math.abs(min - dif); //计算上次减法的减数和差相减所得差的绝对值
            if(newMin === newDif){//减数和差相等时,结束循环
                divisor = newDif; //循环结束是 减数=差,是最大公约数
                break;
            }
            min = newMin;
            dif = newDif;
        }
        num = num / divisor; //分子分母除以最大公约数 获得约分后的结果
        den = den / divisor;
    }
    return {"num":num,"den":den}; //以json格式返回结果
}

调用代码及运行结果:

调用代码:
let input = {"num":49,"den":-91}; //创建输入变量
console.log(chOne02(input)); //调用方法输出结果到控制台

运行结果:
[Running] node "d:\WorkSpace\jsWork\NCMA\chOne\chOne02.js"
{ num: 7, den: -13 }

[Done] exited with code=0 in 0.14 seconds

上面约分的过程可以概括地分为两个运算:求分子、分母的最大公约数,用分子、分母同时除以最大公约数。

求最大公约数我们在其他的地方也可能用到,所以我们可以把求最大公约数的运算提取出来,封装为一个方法,方便后面复用。

很明显,求最大公约数的方法,输入为要求公约数的两个整数,输出为最大公约数。

约分方法输入输出不变。

约分方法:

输入:{分子,分母}

输出:{约分后的分子,约分后的分母}

求最大公约数方法:

输入:{整数1,整数2}

输出:{最大公约数}

晋级版代码:

约分方法:

function chOne03(input){ //以json格式输入:分子num,分母den
    let num = input.num;
    let den = input.den;
    if(den === 0){ //筛选输入,分母不能为0
        return {"code":"001","msg":"分母不能为0,请重新输入!"};
    }
    if(num === 0){ //分子为0时,直接返回结果0
        return{"res":0};
    }
    if(num === den){ //分子分母相等时,直接返回结果1
        return{"res":1};
    }
    let divisor = getDivisor({"num1":num,"num2":den}).divisor; //求分子、分母最大公约数
    num = num / divisor; //分子分母除以最大公约数 获得约分后的结果
    den = den / divisor;
    return {"num":num,"den":den}; //以json格式返回结果
}

求最大公约数方法:

function getDivisor(input){ //求最大公约数方法,以json格式传入参数,包含整数1 num1,整数2 num2
    let num1 = input.num1;
    let num2 = input.num2;
    if(num1 === 0 || num2 === 0){ //两数包含0时,最大公约数就是0
        return{"divisor":0}
    }
    if(Math.abs(num1) === Math.abs(num2)){ //两数绝对值相等时,最大公约数就是传入的整数的绝对值
        return{"divisor":Math.abs(num1)};
    }
    let divisor = 1; //声明一个最大公约数变量divisor,默认值为1
    while(num1 % 2 === 0 && num2 % 2 === 0){ //两数都是偶数时,同时除以2
        num1 = num1 / 2;
        num2 = num2 / 2;
        divisor = divisor * 2; //执行一次除以2的操作,最大公约数就乘2
    }   
    if(num1 % 2 != 0 || num2 % 2 != 0){//两数包含奇数时执行下面操作
        let min = Math.abs(num1) < Math.abs(num2) ? Math.abs(num1) : Math.abs(num2); //取两数中绝对值较小值储存在min中
        let dif = Math.abs(Math.abs(num1) - Math.abs(num2)); //计算两数相减所得差的绝对值 
        while(min != dif){ //上次减法的差和减数不相等时重复下面操作
            let newMin = min < dif ? min : dif; //把上次减法的减数和差中较小值存储在newMin中
            let newDif = Math.abs(min - dif); //计算上次减法的减数和差相减所得差的绝对值
            if(newMin === newDif){//减数和差相等时,结束循环
                divisor = divisor * newDif; //循环结束时 减数=差,这个值乘divisor是最大公约数
                break;
            }
            min = newMin;
            dif = newDif;
        }
    }
    return{"divisor":divisor};
}

调用代码及运行结果:

调用代码:
let input = {"num":49,"den":91}; //创建输入变量
console.log(chOne03(input)); //调用方法输出结果到控制台

运行结果:
[Running] node "d:\WorkSpace\jsWork\NCMA\chOne\chOne03.js"
{ num: 7, den: 13 }

[Done] exited with code=0 in 0.115 seconds

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-29 16:13:51  更:2021-11-29 16:14:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:24:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码