搜尋
首頁web前端js教程使用快速傅立葉變換 (FFT) 乘以大十進制數

Multiplying Large Decimal Numbers Using Fast Fourier Transform (FFT)

介紹

將大十進制數相乘可能在計算上具有挑戰性,尤其是在處理具有許多位數或多個小數位的數字時。傳統的乘法方法對於極大的數字來說效率很低。這就是快速傅立葉變換 (FFT) 發揮作用的地方,它提供了一種強大而高效的演算法,可以以驚人的速度進行大數相乘。

乘法中的應用

  • FFT 透過將數字轉換到頻域、執行逐點乘法,然後應用逆 FFT 來實現多項式或大整數的快速乘法。

大數乘法的挑戰

傳統乘法方法的時間複雜度為 O(n²),其中 n 是位數。對於非常大的數字,這在計算上變得昂貴。基於 FFT 的乘法演算法將這種複雜性降低到 O(n log n),使得處理大數的速度顯著加快。

Cooley-Tukey FFT 的證明大綱

  1. 離散傅立葉轉換 (DFT) 的分解:

    • DFT 定義為:
      Xk=Σn=0N1 xne2π ikn/NNX_k = sum_{n=0}^{N-1} x_n cdot e^{-2pi i cdot kn / N}, Xk = n=0ΣN−1 xn e
      −2πi⋅kn /N, 在哪裡 NN NN
    • 是輸入訊號的大小。 Cooley-Tukey FFT 將計算分解為更小的 DFT N/2N/2 N/2
      透過分離偶數索引和奇數索引項: Xk=Σn=0N/2 1x2ne2πi (2n )k/N Σn=000/ 21x n 1ee πi(2n2n2n2n2 1)k/NNN。 X_k = sum_{n=0}^{N/2-1} x_{2n} cdot e^{-2pi i cdot (2n)k / N} sum_{n=0}^{N /2-1} x_{2n 1} cdot e^{-2pi i cdot (2n 1)k / N}。 Xk k k k k k k k > >= n=0ΣN/2−1 xC🎜>> −2πi⋅(2n)k/N
      n=0
    • Σ N/ 2−1x2n 1 e 這減少為: Xk=k=
      => 🎜> Wk⋅DFT 的奇數項>DFT 的奇數項🎜> X_k = text{偶數項的DFT} W_k cdot text{奇數項的DFT}, Xk​ =DFT 的偶數項 k> 🎜>⋅奇數項的DFT, 在哪裡 Wk=e2πik/N W_k = e^{-2pi i cdot k / N} Wk =e−2πi ⋅k/N
    • .
  2. 遞歸結構

    :
    • 每個大小的 DFT NN NN 被分成兩個大小的 DFT N/2N/2 N/2
    • ,導致遞歸結構。 這種遞歸除法一直持續到大小的基本情況 N=1N = 1 N=1
  3. ,此時 DFT 只是輸入值。

    • 蝴蝶操作
      : 此演算法使用蝶形運算合併較小 DFT 的結果: a==C🎜> Wkv ,b=uWkv,a' = u W_k cdot v,四邊形 ue - W_b' = u - W_k c u - W_k c , 一個=u Wkkk >v,b =u−WW 🎜>k
      ⋅v,⋅v,v, 在哪裡 uu uuu vv vvvvvvv 是較小 DFT 的結果, WkW_k Wk
  4. 代表團結的根源。

    位元反轉排列: 輸入數組根據索引的二進位表示重新排序,以實現就地計算。 時間複雜度:
    • 在每一層遞迴中,都有 NN NN 涉及單位根的計算,遞歸的深度是 日誌2(N)log_2(N) log2 (N)
    • (N)(N)(N)(N)(N)(N) .
    這會產生時間複雜度

  • O(N logN)O(N log N) O(NlogN) . 逆FFT 逆 FFT 類似,但使用 e2π2π kn/NNe^{2pi i> kn / N} e

    2πi⋅kn/N
    • 作為基礎並對結果進行縮放
  1. 1

      /
    • N
    • 1/N
  2. 1/N

    • .
    • 了解 FFT 乘法演算法
  3. FFT 乘法演算法的工作原理有幾個關鍵步驟:
  4. 預處理數字 將輸入數字轉換為數字數組 同時處理整數和小數部分 將陣列填入最接近的 2 次方以進行 FFT 計算 快速傅立葉轉換 使用 FFT 將數字數組轉換為頻域 這將乘法問題轉換為頻域中更簡單的逐點乘法 頻域乘法 對轉換後的陣列執行逐元素乘法 利用複數運算進行高效率計算 逆FFT與結果處理
    • 將相乘後的陣列轉換回時域
    • 處理數位進位
    • 重構最終的十進制數

實施的關鍵組成部分

複數表示

class Complex {
  constructor(re = 0, im = 0) {
    this.re = re;  // Real part
    this.im = im;  // Imaginary part
  }

  // Static methods for complex number operations
  static add(a, b) { /* ... */ }
  static subtract(a, b) { /* ... */ }
  static multiply(a, b) { /* ... */ }
}

Complex 類別對於執行 FFT 運算至關重要,它使我們能夠操作實域和虛域中的數字。

快速傅立葉變換函數

function fft(a, invert = false) {
  // Bit reversal preprocessing
  // Butterfly operations in frequency domain
  // Optional inverse transformation
}

FFT函數是演算法的核心,有效地在時域和頻域之間進行數位轉換。

處理小數

此實作包含處理十進制數的複雜邏輯:

  • 分隔整數和小數部分
  • 追蹤小數點總數
  • 使用正確的小數點位置重建結果

範例用例

// Multiplying large integers
fftMultiply("12345678901234567890", "98765432109876543210")

// Multiplying very large different size integers
fftMultiply("12345678901234567890786238746872364872364987293795843790587345", "9876543210987654321087634875782369487239874023894")

// Multiplying decimal numbers
fftMultiply("123.456", "987.654")

// Handling different decimal places
fftMultiply("1.23", "45.6789")

// Handling different decimal places with large numbers
fftMultiply("1234567890123456789078623874687236487236498.7293795843790587345", "98765432109876543210876348757823694.87239874023894")

性能優勢

  • 時間複雜度:O(n log n) 與傳統方法的 O(n²) 相比
  • 精度:處理具有多個小數位的極大數字
  • 效率:大量乘法運算速度明顯加快

限制和注意事項

  • 需要額外的記憶體來表示複數
  • 浮點運算會影響精確度
  • 與傳統乘法相比,實現更複雜

結論

FFT 乘法演算法代表了一種有效地乘以大數的強大方法。透過利用頻域變換,我們可以以驚人的速度和精度執行複雜的數學運算。

實際應用

  • 科學計算
  • 財務計算
  • 密碼學
  • 大規模數值模擬

進一步閱讀

  • Cooley-Tukey FFT 演算法
  • 數論
  • 計算數學

程式碼

完整的實作如下,為使用快速傅立葉變換方法乘以大十進制數提供了一個強大的解決方案。

/**
 * Fast Fourier Transform (FFT) implementation for decimal multiplication
 * @param {number[]} a - Input array of real numbers
 * @param {boolean} invert - Whether to perform inverse FFT
 * @returns {Complex[]} - Transformed array of complex numbers
 */
class Complex {
  constructor(re = 0, im = 0) {
    this.re = re;
    this.im = im;
  }

  static add(a, b) {
    return new Complex(a.re + b.re, a.im + b.im);
  }

  static subtract(a, b) {
    return new Complex(a.re - b.re, a.im - b.im);
  }

  static multiply(a, b) {
    return new Complex(a.re * b.re - a.im * b.im, a.re * b.im + a.im * b.re);
  }
}

function fft(a, invert = false) {
  let n = 1;
  while (n > 1;
    for (; j & bit; bit >>= 1) {
      j ^= bit;
    }
    j ^= bit;
    if (i > 1;
    for (let i = 0; i  {
    const [intPart, decPart] = numStr.split(".");
    return {
      intPart: intPart || "0",
      decPart: decPart || "",
      totalDecimalPlaces: (decPart || "").length,
    };
  };

  const parsed1 = parseNumber(num1);
  const parsed2 = parseNumber(num2);

  // Combine numbers removing decimal point
  const combinedNum1 = parsed1.intPart + parsed1.decPart;
  const combinedNum2 = parsed2.intPart + parsed2.decPart;

  // Total decimal places
  const totalDecimalPlaces =
    parsed1.totalDecimalPlaces + parsed2.totalDecimalPlaces;

  // Convert to digit arrays (least significant first)
  const a = combinedNum1.split("").map(Number).reverse();
  const b = combinedNum2.split("").map(Number).reverse();

  // Determine result size and pad
  const resultSize = a.length + b.length;
  const fftSize = 1  new Complex(x, 0));
  const complexB = b.map((x) => new Complex(x, 0));

  // Perform FFT
  const fftA = fft(complexA);
  const fftB = fft(complexB);

  // Pointwise multiplication in frequency domain
  const fftProduct = new Array(fftSize);
  for (let i = 0; i = 10) {
      result[i + 1] += Math.floor(result[i] / 10);
      result[i] %= 10;
    }
  }

  // Remove leading zeros and convert to string
  while (result.length > 1 && result[result.length - 1] === 0) {
    result.pop();
  }

  // Insert decimal point
  const resultStr = result.reverse().join("");
  if (totalDecimalPlaces === 0) {
    return resultStr;
  }

  // Handle case where result might be shorter than decimal places
  if (resultStr.length 



<h3>
  
  
  輸出
</h3>



<pre class="brush:php;toolbar:false">// Example Usage - Self verify using Python
console.log(
  "Product of integers:",
  fftMultiply("12345678901234567890", "98765432109876543210")
);
console.log("Product of decimals:", fftMultiply("123.456", "987.654"));
console.log("Product of mixed decimals:", fftMultiply("12.34", "56.78"));
console.log(
  "Product with different decimal places:",
  fftMultiply("1.23", "45.6789")
);
console.log(
  "Product with large integers:",
  fftMultiply(
    "12345678901234567890786238746872364872364987293795843790587345",
    "9876543210987654321087634875782369487239874023894"
  )
);
const num1 = "1234567890123456789078623874687236487236498.7293795843790587345";
const num2 = "98765432109876543210876348757823694.87239874023894";
console.log("Product:", fftMultiply(num1, num2));
Product of integers: 1219326311370217952237463801111263526900
Product of decimals: 121931.812224
Product of mixed decimals: 700.6652
Product with different decimal places: 56.185047
Product with large integers: 121932631137021795232593613105722759976860134207381319681901040774443113318245930967231822167723255326824021430
Product: 121932631137021795232593613105722759976860134207381319681901040774443113318245.93096723182216772325532682402143

以上是使用快速傅立葉變換 (FFT) 乘以大十進制數的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
JavaScript的核心:它是在C還是C上構建的?JavaScript的核心:它是在C還是C上構建的?May 05, 2025 am 12:07 AM

javascriptisnotbuiltoncorc; sanInterpretedlanguagethatrunsonenginesoftenwritteninc.1)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

JavaScript應用程序:從前端到後端JavaScript應用程序:從前端到後端May 04, 2025 am 12:12 AM

JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

Python vs. JavaScript:您應該學到哪種語言?Python vs. JavaScript:您應該學到哪種語言?May 03, 2025 am 12:10 AM

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

JavaScript框架:為現代網絡開發提供動力JavaScript框架:為現代網絡開發提供動力May 02, 2025 am 12:04 AM

JavaScript框架的強大之處在於簡化開發、提升用戶體驗和應用性能。選擇框架時應考慮:1.項目規模和復雜度,2.團隊經驗,3.生態系統和社區支持。

JavaScript,C和瀏覽器之間的關係JavaScript,C和瀏覽器之間的關係May 01, 2025 am 12:06 AM

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr

node.js流帶打字稿node.js流帶打字稿Apr 30, 2025 am 08:22 AM

Node.js擅長於高效I/O,這在很大程度上要歸功於流。 流媒體匯總處理數據,避免內存過載 - 大型文件,網絡任務和實時應用程序的理想。將流與打字稿的類型安全結合起來創建POWE

Python vs. JavaScript:性能和效率注意事項Python vs. JavaScript:性能和效率注意事項Apr 30, 2025 am 12:08 AM

Python和JavaScript在性能和效率方面的差異主要體現在:1)Python作為解釋型語言,運行速度較慢,但開發效率高,適合快速原型開發;2)JavaScript在瀏覽器中受限於單線程,但在Node.js中可利用多線程和異步I/O提升性能,兩者在實際項目中各有優勢。

JavaScript的起源:探索其實施語言JavaScript的起源:探索其實施語言Apr 29, 2025 am 12:51 AM

JavaScript起源於1995年,由布蘭登·艾克創造,實現語言為C語言。 1.C語言為JavaScript提供了高性能和系統級編程能力。 2.JavaScript的內存管理和性能優化依賴於C語言。 3.C語言的跨平台特性幫助JavaScript在不同操作系統上高效運行。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),