【學Rust寫CAD】31 muldiv255函數(muldiv255.rs)

源碼

// Calculates floor(a*b/255 + 0.5)
#[inline]
pub fn muldiv255(a: u32, b: u32) -> u32 {// The deriviation for this formula can be// found in "Three Wrongs Make a Right" by Jim Blinn.let tmp = a * b + 128;(tmp + (tmp >> 8)) >> 8
}

代碼分析

這個 muldiv255 函數是一個高效的實現,用于計算 floor(a * b / 255 + 0.5),也就是將兩個無符號整數 a 和 b 相乘,然后除以 255,并進行四舍五入。這種計算在圖像處理中很常見,比如在 alpha 混合(alpha blending)或顏色空間轉換時。

步驟分解:
  1. a * b + 128:
  • 首先計算 a * b,然后加上 128。這個 128 的作用是為了后續的四舍五入(因為 255 / 2 = 127.5,所以加 128 可以確保正確的舍入)。
  1. tmp + (tmp >> 8):
  • tmp >> 8 相當于 tmp / 256(右移 8 位相當于除以 2^8)。

  • 然后 tmp + (tmp >> 8) 相當于 tmp + tmp / 256。

  1. 8:

  • 最后右移 8 位,相當于除以 256。

為什么這個公式有效?

這個方法的數學原理來自 Jim Blinn 的文章 “Three Wrongs Make a Right”,它利用了近似計算來避免昂貴的除法運算(因為整數除法在 CPU 上通常比乘法和移位慢)。

  • 原本的計算是 (a * b + 127) / 255(四舍五入)。

  • 但 (a * b + 128) * 257 / 65536(即 (tmp + (tmp >> 8)) >> 8)是一個近似計算,可以高效地用移位和加法實現。

數學推導:

  1. 我們希望計算 (a * b + 127) / 255(四舍五入)。

  2. 可以近似為 (a * b + 128) * (256 + 1) / 65536(因為 255 ≈ 65536 / 257)。

展開后:

(a * b + 128) * (256 + 1) / 65536
= (256*(a*b + 128) + (a*b + 128)) / 65536
= ( (a*b + 128) << 8 + (a*b + 128) ) >> 16
= (tmp << 8 + tmp) >> 16
= (tmp + (tmp >> 8)) >> 8

最終得到 (tmp + (tmp >> 8)) >> 8。

示例

假設 a = 100, b = 200:

  1. tmp = 100 * 200 + 128 = 20000 + 128 = 20128

  2. tmp >> 8 = 20128 / 256 = 78

  3. tmp + (tmp >> 8) = 20128 + 78 = 20206

20206 >> 8 = 20206 / 256 = 78(實際 100 * 200 / 255 ≈ 78.431,四舍五入得 78)

為什么不用 (a * b + 127) / 255?

雖然 (a * b + 127) / 255 也能得到正確結果,但:

  • 除法 (/ 255) 在 CPU 上通常比移位和加法慢。

  • 這個優化方法避免了除法,改用移位和加法,性能更高。

適用場景

  • 圖像處理(如 alpha 混合、顏色計算)。

  • 需要高效計算 (a * b) / 255 并四舍五入的情況。

總結

這個函數巧妙地利用移位和加法來近似計算 (a * b) / 255 并四舍五入,避免了昂貴的除法運算,是一種高效的位操作優化方法。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/75761.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/75761.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/75761.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

藍橋云客--團隊賽

2.團隊賽【算法賽】 - 藍橋云課 問題描述 藍橋杯最近推出了一項團隊賽模式&#xff0c;要求三人組隊參賽&#xff0c;并規定其中一人必須擔任隊長。隊長的資格很簡單&#xff1a;其程序設計能力值必須嚴格大于其他兩名隊友程序設計能力值的總和。 小藍、小橋和小杯正在考慮報名…

#Linux內存管理# 假設設備上安裝了一塊2G的物理內存,在系統啟動時,ARM Linux內核是如何映射的?

在ARM Linux系統啟動過程中&#xff0c;對2GB物理內存的映射實現分為以下幾個關鍵階段&#xff1a; 一、設備樹解析與內存信息獲取 1.設備樹定義 物理內存范圍通過設備樹&#xff08;DTS&#xff09;的memory節點定義&#xff0c;例如&#xff1a; memory60000000 { device_ty…

使用MATIO庫讀取Matlab數據文件中的多維數組

使用MATIO庫讀取Matlab數據文件中的多維數組 MATIO是一個用于讀寫Matlab數據文件(.mat)的開源C庫。下面是一個完整的示例程序&#xff0c;展示如何使用MATIO庫讀取Matlab數據文件中的多維數組。 示例程序 #include <stdio.h> #include <stdlib.h> #include <…

react+antd中做一個外部按鈕新增 表格內部本地新增一條數據并且支持編輯刪除(無難度上手)

需求背景 做一個可以外部控制新增刷新表格 表格內部可以編輯刪除 類似下方需求圖 實現過程 因為我實現時有兩個這樣的表格 所以我的事件里面會有傳參用于判斷 可忽略傳參判斷部分 代碼中有formatMessage部分為國際化可忽略 <div style{{ marginBottom: 10px, margin…

【深度學習新浪潮】視覺與多模態大模型文字生成技術研究進展與產品實踐

一、研究進展 跨模態架構創新 原生多模態模型:微軟KOSMOS系列通過統一框架支持文本、圖像、語音等多模態輸入輸出,實現跨模態推理與遷移。例如,KOSMOS-2.5可處理文本密集圖像,生成結構化文本描述,并通過重采樣模塊優化視覺與語言的對齊。混合專家架構:第三代模型(如Deep…

重生之我是去噪高手——diffusion model

diffusion model是如何運作的&#xff1f; 想象一下&#xff0c;你有一張清晰的圖片。擴散模型的核心思想分為兩個過程&#xff1a; 前向過程&#xff08;Forward Process / Diffusion Process&#xff09;&#xff1a;逐步加噪反向過程&#xff08;Reverse Process / Denois…

華為項目管理“六步一法”方法論全解析:目標確認、項目活動分解與日事清系統協同

大家都知道&#xff0c;項目管理在現在各個行業里都是越來越重要了。 要是搞不好&#xff0c;項目就會拖沓&#xff0c;甚至走向失敗。 今天咱們就來聊聊華為是怎么做項目管理的&#xff0c;比較知名的就是它們的“六步一法”。華為通過“六步一法”來進行項目管理&#xff0…

OpenCV 圖形API(9)用于執行矩陣與標量之間的逐元素除法操作函數divC()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 矩陣除以標量。 該函數 divC 將矩陣 src 的每個元素除以給定的標量值&#xff1a; dst(I) saturate(src(I)*scale/divisor) \texttt{dst(I) s…

單例模式(懶漢模式/餓漢模式)

相關概念參考&#xff1a;【C】C 單例模式總結&#xff08;5種單例實現方法&#xff09;_單例模式c實現-CSDN博客 #include<iostream>class LazySingle{ public:static LazySingle& getInstance(){static LazySingle instance;return instance;}void hello(){std::c…

RocketMQ初認識

ProducerCustomerNameServer: Broker的注冊服務發現中心BrokerServer:主要負責消息的存儲、投遞和查詢以及服務高可用保證 RocketMQ的集群部署&#xff1a; 單個master的分支多個Master 模式&#xff1a;集群中有多個 Master 節點&#xff0c;彼此之間相互獨立。生產者可以將消…

Maven/Gradle的講解

一、為什么需要構建工具? 在理解 Maven/Gradle 之前,先明確它們解決的問題: ??依賴管理??:項目中可能需要引入第三方庫(如 Spring、JUnit 等),手動下載和管理這些庫的版本非常麻煩。??標準化構建流程??:編譯代碼、運行測試、打包成 JAR/WAR 文件等步驟需要自動…

基于SSM的車輛管理系統的設計與實現(代碼+數據庫+LW)

摘要 當下&#xff0c;正處于信息化的時代&#xff0c;許多行業順應時代的變化&#xff0c;結合使用計算機技術向數字化、信息化建設邁進。以前企業對于車輛信息的管理和控制&#xff0c;采用人工登記的方式保存相關數據&#xff0c;這種以人力為主的管理模式已然落后。本人結…

嵌入式硬件篇---JSON通信以及解析

文章目錄 前言一、JSON特點語法簡單數據格式靈活輕量化跨語言使用二、JSON數據結構對象數組三、JSON在單片機之間通信的應用數據封裝與傳輸四、JSON示例代碼五、JSON在上位機與單片機之間通信的應用數據交互六、JSON示例代碼七、JSON解析與生成解析生成八、Python中的數據解析1…

【C#】.net core 6.0 依賴注入常見問題之一,在構造函數使用的類,都需要注入到容器里,否則會提示如下報錯,讓DeepSeek找找原因,看看效果

&#x1f339;歡迎來到《小5講堂》&#x1f339; &#x1f339;這是《C#》系列文章&#xff0c;每篇文章將以博主理解的角度展開講解。&#x1f339; &#x1f339;溫馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不對之處望指正&#xff01;&#…

《P1072 [NOIP 2009 提高組] Hankson 的趣味題》

題目描述 Hanks 博士是 BT&#xff08;Bio-Tech&#xff0c;生物技術) 領域的知名專家&#xff0c;他的兒子名叫 Hankson。現在&#xff0c;剛剛放學回家的 Hankson 正在思考一個有趣的問題。 今天在課堂上&#xff0c;老師講解了如何求兩個正整數 c1? 和 c2? 的最大公約數…

nginx的自動跳轉https

mkdir /usr/local/nginx/certs/ 創建一個目錄 然后用openssl生成證書 編輯nginx的配置文件 自動跳轉成功 做一個優化&#xff0c;如果訪問的時候后面加了其他的uri也一起自動跳轉了

力扣刷題——508.出現次數最多的子樹和

給你一個二叉樹的根結點 root &#xff0c;請返回出現次數最多的子樹元素和。如果有多個元素出現的次數相同&#xff0c;返回所有出現次數最多的子樹元素和&#xff08;不限順序&#xff09;。 一個結點的 「子樹元素和」 定義為以該結點為根的二叉樹上所有結點的元素之和&…

2025/4/2 心得

第一題 題目描述 給定1001個范圍在[1,1000]的數字&#xff0c;保證只有1個數字重復出現2次&#xff0c;其余數字只出現1次。試用O(n)時間復雜度來求出出現2次的這個數字。 不允許用數組 輸入格式 第一行&#xff1a;一個整數1001&#xff1b; 第二行&#xff1a;1001個用…

0基礎 | 硬件 | NE555芯片 二

目錄 “雙穩態電路之按鍵開關LED” 版本一&#xff1a; 版本二&#xff1a; “單穩態電路之延時自動關” 版本一 “無穩態電路之延時自動開關” 版本一&#xff1a; 版本二 “雙穩態電路之按鍵開關LED” 版本一&#xff1a; 按鍵1 使2腳輸入低電平&#xff0c;則3輸出…

Python實現鏈接KS3,并將文件數據上傳到KS3

前言 本文是該專欄的第55篇,后面會持續分享python的各種干貨知識,值得關注。 說到KS3,首先想到的是金山云提供的對象存儲服務。 相信或多或少的同學,在工作項目中也會遇到KS3相關的需求。比如說,現在有大批量的數據文件需要通過Python,上傳到KS3中。對此,需要怎么去做…