math.js源碼的簡單介紹

本文目錄一覽:

number-precision 實現js高精度運算 源碼

type numType = number | string;

/**

* @desc 解決浮動運算問題,避免小數點後產生多位數和計算精度損失。

* 問題示例:2.3 + 2.4 = 4.699999999999999,1.0 – 0.9 = 0.09999999999999998

*/

/**

* 把錯誤的數據轉正

* strip(0.09999999999999998)=0.1

*/

function strip(num: numType, precision = 15): number {

  return +parseFloat(Number(num).toPrecision(precision));

}

/**

* Return digits length of a number

* @param {*number} num Input number

*/

function digitLength(num: numType): number {

  // Get digit length of e

  const eSplit = num.toString().split(/[eE]/);

  const len = (eSplit[0].split(‘.’)[1] || ”).length – +(eSplit[1] || 0);

  return len 0 ? len : 0;

}

/**

* 把小數轉成整數,支持科學計數法。如果是小數則放大成整數

* @param {*number} num 輸入數

*/

function float2Fixed(num: numType): number {

  if (num.toString().indexOf(‘e’) === -1) {

    return Number(num.toString().replace(‘.’, ”));

  }

  const dLen = digitLength(num);

  return dLen 0 ? strip(Number(num) * Math.pow(10, dLen)) : Number(num);

}

/**

* 檢測數字是否越界,如果越界給出提示

* @param {*number} num 輸入數

*/

function checkBoundary(num: number) {

  if (_boundaryCheckingState) {

    if (num Number.MAX_SAFE_INTEGER || num Number.MIN_SAFE_INTEGER) {

      console.warn(`${num} is beyond boundary when transfer to integer, the results may not be accurate`);

    }

  }

}

/**

* 精確乘法

*/

function times(num1: numType, num2: numType, …others: numType[]): number {

  if (others.length 0) {

    return times(times(num1, num2), others[0], …others.slice(1));

  }

  const num1Changed = float2Fixed(num1);

  const num2Changed = float2Fixed(num2);

  const baseNum = digitLength(num1) + digitLength(num2);

  const leftValue = num1Changed * num2Changed;

  checkBoundary(leftValue);

  return leftValue / Math.pow(10, baseNum);

}

/**

* 精確加法

*/

function plus(num1: numType, num2: numType, …others: numType[]): number {

  if (others.length 0) {

    return plus(plus(num1, num2), others[0], …others.slice(1));

  }

  const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));

  return (times(num1, baseNum) + times(num2, baseNum)) / baseNum;

}

/**

* 精確減法

*/

function minus(num1: numType, num2: numType, …others: numType[]): number {

  if (others.length 0) {

    return minus(minus(num1, num2), others[0], …others.slice(1));

  }

  const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));

  return (times(num1, baseNum) – times(num2, baseNum)) / baseNum;

}

/**

* 精確除法

*/

function divide(num1: numType, num2: numType, …others: numType[]): number {

  if (others.length 0) {

    return divide(divide(num1, num2), others[0], …others.slice(1));

  }

  const num1Changed = float2Fixed(num1);

  const num2Changed = float2Fixed(num2);

  checkBoundary(num1Changed);

  checkBoundary(num2Changed);

  // fix: 類似 10 ** -4 為 0.00009999999999999999,strip 修正

  return times(num1Changed / num2Changed, strip(Math.pow(10, digitLength(num2) – digitLength(num1))));

}

/**

* 四捨五入

*/

function round(num: numType, ratio: number): number {

  const base = Math.pow(10, ratio);

  return divide(Math.round(times(num, base)), base);

}

let _boundaryCheckingState = true;

/**

* 是否進行邊界檢查,默認開啟

* @param flag 標記開關,true 為開啟,false 為關閉,默認為 true

*/

// 這裡可以設置邊界檢查(默認是true)

function enableBoundaryChecking(flag = true) {

  _boundaryCheckingState = flag;

}

// 輸出上面的方法

export { strip, plus, minus, times, divide, round, digitLength, float2Fixed, enableBoundaryChecking };

export default {

  strip,

  plus,

  minus,

  times,

  divide,

  round,

  digitLength,

  float2Fixed,

  enableBoundaryChecking,

};

前端自動化測試框架Jest 基礎入門-

  一、引言

前端這幾年發展的非常迅速,我們的系統的功能正在變的越來越複雜,這對我們的前端工程化能力提出了更高的要求,聽到工程化,大家的第一反應肯定是高質量的代碼設計和高質量的代碼實現。

但實際上,前端 自動化測試 也是前端工程化裡面非常重要的一個環節。

   二、 Jest 基礎入門

一個普通前端聽到自動化測試,第一反應可能是:我工作這麼多年也沒寫過測試,這個東西有用嗎?

答:非常有用

如果你打開GitHub,去看一下流行的開源庫或者框架的源碼,你會發現,在這些源碼裡面,全部都包含了大量的自動化測試的代碼。比如antd、lodash、再比如vue、react、echarts、redux等等……

開源的工具需要穩定性,而引入前端自動化測試為開源項目提供穩定性,是再好不過的選擇了。

三、學習前提

閱讀這篇 文章 需要以下知識儲備:

·js、es6 基礎語法

·node、npm 相關知識

·git 的相關操作

·react或者vue,至少了解一個

·狀態管理工具,至少了解一個

四、背景及原理

首先在任意目錄下創建一個math.js文件,假設這個文件是一個數學庫,裡面定義兩個函數,分別是加法和減法:

// math.js

function add(a, b) {

return a + b;

}

function minus(a, b) {

return a – b;

}

這時候我們可以在業務代碼里去使用這個數學庫。

但是,假如,上面的minus函數我們不小心寫錯了,把減法寫成了乘法,如果直接在業務代碼中使用這個方法,就會帶來無法預期的bug。

所以這時候,我們就需要對math.js這個公共庫進行自動化測試,確保沒問題之後,再讓業務組件去調用,這樣就會保證不會出特別多的bug了。

我們可以這樣做:

在該目錄下創建一個math.test.js文件,然後寫一點測試代碼:

const result = add(3, 7);

const expect = 10;

if (result !== expect) {

throw new Error(`3 + 7 應該等於${expect},結果卻是${result}`);

}

const result = minus(3, 3);

const expect = 0;

if (result !== expect) {

throw new Error(`3 – 3 應該等於${expect},結果卻是${result}`);

}

這時候我們運行這段代碼,會發現沒有拋出任何異常,說明這兩個 測試用例 都通過了。

這就是自動化測試最原始的雛形。

然後我們思考一個問題,如何將這堆代碼進行簡化,做成一個公用的函數,比如這樣:

// 測試 3 + 3 是否等於 6

expect(add(3, 3)).toBe(6);

// 測試 3 – 3 是否等於 0

expect(minus(3, 3)).toBe(0);

expect 方法實現:

function expect(result) {

return {

toBe(actual) {

if (result !== actual) {

throw new Error(“預期值和實際值不相等”);

}

},

};

}

這時候我們運行這段代碼,會發現沒有拋出任何異常,說明這兩個測試用例都通過了。

雖然實現了 expect 函數,但是報錯的內容始終是一樣的,我們不知道是具體哪個方法出現了問題,這時候我們就會想到,我們需要將這個 expect 方法進一步做改良,我們如果能在 expect 方法外部再包裝一層,就可以多傳遞一些額外的內容,比如創造這樣的寫法:

test(“測試加法 3 + 3”, () = {

expect(add(3, 3)).toBe(6);

});

test(“測試減法 3 – 3”, () = {

expect(minus(3, 3)).toBe(0);

});

這樣封裝之後,我們既能進行測試,又能得到測試的描述。

test 方法實現:

function test(desc, fn) {

try {

fn();

console.log(`${desc} 通過測試`);

} catch {

console.log(`${desc} 沒有通過測試`);

}

}

所以前端自動化測試到底是什麼?

答:實際上就是寫了一段其它的用來測試的js代碼,通過測試代碼去運行業務代碼,判斷實際結果是否滿足預期結果,如果滿足,就是沒有問題,如果不滿足,就是有問題。

上面實現的 expect 方法 和 test 方法 實際上和主流的前端自動化測試框架 jest 裡面的語法是完全一致的。所以上面的示例代碼可以理解為 jest 的底層實現原理。

math是nodejs模塊嗎

是的

JavaScript起初並沒有內置的模塊系統,CommonJS社區為了使JavaScript可以提供一個類似Python、Ruby等的標準庫,自己實現了一套API填補了JavaScript沒有內置模塊的空白。

CommonJS規範本身涵蓋了模塊、二進位、Buffer、文件系統、包管理等內容,而NodeJS正是借鑒了CommonJS規範的模塊系統,自身實現了一套非常易用的模塊系統。CommonJS對模塊的定義可分為三部分:模塊引用(require)、模塊定義(exports、module)、模塊標識。

模塊引用:require函數用於引入外部模塊到當前上下文中

模塊定義:exports導出當前模塊的變數或方法,是唯一導出的出口。在模塊中,還有一個module對象,它代表模塊自身,且exports是module對象的屬性。

模塊標識:就是傳遞給require方法的參數。

在NodeJS中,每一個文件就是一個模塊,其內部定義的變數是屬於這個模塊的,不會對外暴露,也就是說不會污染全局變數。因此以上math.js模塊定義的PI常量不會作為全局變數存在,而是被包裹在NodeJS的模塊包裝器中,作為局部變數存在。math.js文件中通過exports對象導出該模塊下的circle方法,在main.js文件中通過require方法引入了circle方法。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/311582.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2025-01-05 13:24
下一篇 2025-01-05 13:24

相關推薦

  • JS Proxy(array)用法介紹

    JS Proxy(array)可以說是ES6中非常重要的一個特性,它可以代理一個數組,監聽數據變化並進行攔截、處理。在實際開發中,使用Proxy(array)可以方便地實現數據的監…

    編程 2025-04-29
  • Python簡單數學計算

    本文將從多個方面介紹Python的簡單數學計算,包括基礎運算符、函數、庫以及實際應用場景。 一、基礎運算符 Python提供了基礎的算術運算符,包括加(+)、減(-)、乘(*)、除…

    編程 2025-04-29
  • Python滿天星代碼:讓編程變得更加簡單

    本文將從多個方面詳細闡述Python滿天星代碼,為大家介紹它的優點以及如何在編程中使用。無論是剛剛接觸編程還是資深程序員,都能從中獲得一定的收穫。 一、簡介 Python滿天星代碼…

    編程 2025-04-29
  • 雲智直聘 源碼分析

    本文將會對雲智直聘的源碼進行分析,包括前端頁面和後端代碼,幫助讀者了解其架構、技術實現以及對一些常見的問題進行解決。通過本文的閱讀,讀者將會了解到雲智直聘的特點、優勢以及不足之處,…

    編程 2025-04-29
  • Python海龜代碼簡單畫圖

    本文將介紹如何使用Python的海龜庫進行簡單畫圖,並提供相關示例代碼。 一、基礎用法 使用Python的海龜庫,我們可以控制一個小海龜在窗口中移動,並利用它的「畫筆」在窗口中繪製…

    編程 2025-04-29
  • 解析js base64並轉成unit

    本文將從多個方面詳細介紹js中如何解析base64編碼並轉成unit格式。 一、base64編碼解析 在JavaScript中解析base64編碼可以使用atob()函數,它會將b…

    編程 2025-04-29
  • Node.js使用Body-Parser處理HTTP POST請求時,特殊字元無法返回的解決方法

    本文將解決Node.js使用Body-Parser處理HTTP POST請求時,特殊字元無法返回的問題。同時,給出一些相關示例代碼,以幫助讀者更好的理解並處理這個問題。 一、問題解…

    編程 2025-04-29
  • Python櫻花樹代碼簡單

    本文將對Python櫻花樹代碼進行詳細的闡述和講解,幫助讀者更好地理解該代碼的實現方法。 一、簡介 櫻花樹是一種圖形效果,它的實現方法比較簡單。Python中可以通過turtle這…

    編程 2025-04-28
  • t3.js:一個全能的JavaScript動態文本替換工具

    t3.js是一個非常流行的JavaScript動態文本替換工具,它是一個輕量級庫,能夠很容易地實現文本內容的遞增、遞減、替換、切換以及其他各種操作。在本文中,我們將從多個方面探討t…

    編程 2025-04-28
  • Python大神作品:讓編程變得更加簡單

    Python作為一種高級的解釋性編程語言,一直被廣泛地運用於各個領域,從Web開發、遊戲開發到人工智慧,Python都扮演著重要的角色。Python的代碼簡潔明了,易於閱讀和維護,…

    編程 2025-04-28

發表回復

登錄後才能評論