對數函數分段定點實現

目錄

一、原理介紹? ? ? ??

二、代碼實現

三、結果顯示

四、移植到C語言中的應用

4.1. 定義定點數配置和參數

4.2. 實現分段查找函數

4.3. 實現 log10 近似計算函數

4.4. (可選)定點數轉浮點數


一、原理介紹? ? ? ??

????????之前的博文對數函數分段線性實現講解了理論方法和誤差分析。這篇博文講解其定點實現方法。

二、代碼實現

import math# 定點數配置
FRACTIONAL_BITS = 16  # 小數部分位數
INTEGER_BITS = 32 - FRACTIONAL_BITS  # 整數部分位數
SCALE_FACTOR = 1 << FRACTIONAL_BITS  # 2^16 = 65536def generate_segment_points():"""生成所有分段點"""points = [0, 1, 2, 3, 4, 5, 6, 7]# 后續以2的指數為點,直到不超過4095exp = 3  # 2^3 = 8,接續7之后while True:point = 2 ** expif point > 4095:breakpoints.append(point)exp += 1# 確保最后一個點是4095if points[-1] < 4095:points.append(4095)return pointsdef float_to_fixed(value):"""將浮點數轉換為定點數表示"""# 計算最大值和最小值max_val = (1 << INTEGER_BITS) - (1.0 / SCALE_FACTOR)min_val = -(1 << INTEGER_BITS)# 截斷到范圍內if value > max_val:value = max_valelif value < min_val:value = min_val# 轉換為定點數fixed_point = int(round(value * SCALE_FACTOR))# 確保在32位有符號整數范圍內if fixed_point > 0x7FFFFFFF:fixed_point = 0x7FFFFFFFelif fixed_point < -0x80000000:fixed_point = -0x80000000return fixed_pointdef fixed_to_float(fixed_value):"""將定點數轉換回浮點數"""return fixed_value / SCALE_FACTORdef calculate_segments(points):"""計算每段的斜率和截距(浮點和定點)"""segments = []for i in range(len(points) - 1):x1 = points[i]x2 = points[i + 1]# 處理x=0的特殊情況(log10(0)無定義,用log10(1)代替)if x1 == 0:y1 = math.log10(1)  # log10(1) = 0else:y1 = math.log10(x1)y2 = math.log10(x2)# 計算斜率和截距(浮點)if x2 == x1:k_float = 0.0else:k_float = (y2 - y1) / (x2 - x1)b_float = y1 - k_float * x1# 轉換為定點數k_fixed = float_to_fixed(k_float)b_fixed = float_to_fixed(b_float)# 還原定點數為浮點數,用于對比k_fixed_float = fixed_to_float(k_fixed)b_fixed_float = fixed_to_float(b_fixed)segments.append({'segment_id': i,'start': x1,'end': x2,# 浮點參數'k_float': k_float,'b_float': b_float,# 定點參數(整數表示)'k_fixed': k_fixed,'b_fixed': b_fixed,# 定點參數還原為浮點(用于精度參考)'k_fixed_float': k_fixed_float,'b_fixed_float': b_fixed_float})return segmentsdef main():# 生成分段點points = generate_segment_points()print(f"分段點: {points}")print(f"共{len(points)-1}段直線\n")# 計算分段參數segments = calculate_segments(points)# 輸出定點數配置print("定點數配置:")print(f"總位數: 32位")print(f"整數部分: {INTEGER_BITS}位")print(f"小數部分: {FRACTIONAL_BITS}位")print(f"縮放因子: 2^{FRACTIONAL_BITS} = {SCALE_FACTOR}\n")# 顯示斜率對比print("斜率(k)參數對比:")print(f"{'分段ID':<8} {'x范圍':<12} {'浮點值':<18} {'定點整數值':<18} {'定點還原浮點值':<18}")print("-" * 80)for seg in segments:x_range = f"[{seg['start']}, {seg['end']}]"print(f"{seg['segment_id']:<8} {x_range:<12} {seg['k_float']:<18.10f} "f"{seg['k_fixed']:<18} {seg['k_fixed_float']:<18.10f}")# 顯示截距對比print("\n截距(b)參數對比:")print(f"{'分段ID':<8} {'x范圍':<12} {'浮點值':<18} {'定點整數值':<18} {'定點還原浮點值':<18}")print("-" * 80)for seg in segments:x_range = f"[{seg['start']}, {seg['end']}]"print(f"{seg['segment_id']:<8} {x_range:<12} {seg['b_float']:<18.10f} "f"{seg['b_fixed']:<18} {seg['b_fixed_float']:<18.10f}")# 生成嵌入式可用的C語言數組定義print("\n嵌入式C語言參數數組:")print("/* 分段點定義 */")print(f"const uint16_t segment_points[] = {{ {', '.join(map(str, points))} }};")print(f"const uint8_t num_segments = {len(segments)};\n")print("/* 斜率(k)定點數值組 */")k_values = [str(seg['k_fixed']) for seg in segments]print(f"const int32_t k_fixed[] = {{ {', '.join(k_values)} }};\n")print("/* 截距(b)定點數值組 */")b_values = [str(seg['b_fixed']) for seg in segments]print(f"const int32_t b_fixed[] = {{ {', '.join(b_values)} }};")if __name__ == "__main__":main()

三、結果顯示

段點: [0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4095]
共17段直線定點數配置:
總位數: 32位
整數部分: 16位
小數部分: 16位
縮放因子: 2^16 = 65536斜率(k)參數對比:
分段ID     x范圍          浮點值                定點整數值              定點還原浮點值           
--------------------------------------------------------------------------------
0        [0, 1]       0.0000000000       0                  0.0000000000      
1        [1, 2]       0.3010299957       19728              0.3010253906      
2        [2, 3]       0.1760912591       11540              0.1760864258      
3        [3, 4]       0.1249387366       8188               0.1249389648      
4        [4, 5]       0.0969100130       6351               0.0969085693      
5        [5, 6]       0.0791812460       5189               0.0791778564      
6        [6, 7]       0.0669467896       4387               0.0669403076      
7        [7, 8]       0.0579919470       3801               0.0579986572      
8        [8, 16]      0.0376287495       2466               0.0376281738      
9        [16, 32]     0.0188143747       1233               0.0188140869      
10       [32, 64]     0.0094071874       617                0.0094146729      
11       [64, 128]    0.0047035937       308                0.0046997070      
12       [128, 256]   0.0023517968       154                0.0023498535      
13       [256, 512]   0.0011758984       77                 0.0011749268      
14       [512, 1024]  0.0005879492       39                 0.0005950928      
15       [1024, 2048] 0.0002939746       19                 0.0002899170      
16       [2048, 4095] 0.0001470073       10                 0.0001525879      截距(b)參數對比:
分段ID     x范圍          浮點值                定點整數值              定點還原浮點值           
--------------------------------------------------------------------------------
0        [0, 1]       0.0000000000       0                  0.0000000000      
1        [1, 2]       -0.3010299957      -19728             -0.3010253906     
2        [2, 3]       -0.0511525224      -3352              -0.0511474609     
3        [3, 4]       0.1023050449       6705               0.1023101807      
4        [4, 5]       0.2144199393       14052              0.2144165039      
5        [5, 6]       0.3030637741       19862              0.3030700684      
6        [6, 7]       0.3764705126       24672              0.3764648438      
7        [7, 8]       0.4391544112       28780              0.4391479492      
8        [8, 16]      0.6020599913       39457              0.6020660400      
9        [16, 32]     0.9030899870       59185              0.9030914307      
10       [32, 64]     1.2041199827       78913              1.2041168213      
11       [64, 128]    1.5051499783       98642              1.5051574707      
12       [128, 256]   1.8061799740       118370             1.8061828613      
13       [256, 512]   2.1072099696       138098             2.1072082520      
14       [512, 1024]  2.4082399653       157826             2.4082336426      
15       [1024, 2048] 2.7092699610       177555             2.7092742920      
16       [2048, 4095] 3.0102589912       197280             3.0102539062      嵌入式C語言參數數組:
/* 分段點定義 */
const uint16_t segment_points[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4095 };
const uint8_t num_segments = 17;/* 斜率(k)定點數值組 */
const int32_t k_fixed[] = { 0, 19728, 11540, 8188, 6351, 5189, 4387, 3801, 2466, 1233, 617, 308, 154, 77, 39, 19, 10 };/* 截距(b)定點數值組 */
const int32_t b_fixed[] = { 0, -19728, -3352, 6705, 14052, 19862, 24672, 28780, 39457, 59185, 78913, 98642, 118370, 138098, 157826, 177555, 197280 };

四、移植到C語言中的應用

4.1. 定義定點數配置和參數

首先在 C 文件中定義定點數配置(需與 Python 中一致)和從 Python 復制的參數:

#include <stdint.h>  // 用于uint16_t、int32_t等類型// 定點數配置(必須與Python代碼中的設置一致)
#define FRACTIONAL_BITS 16  // 小數部分位數(與Python的FRACTIONAL_BITS相同)
#define SCALE_FACTOR (1 << FRACTIONAL_BITS)  // 2^16 = 65536// 從Python輸出復制的分段參數
const uint16_t segment_points[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4095};
const uint8_t num_segments = sizeof(segment_points) / sizeof(segment_points[0]) - 1;const int32_t k_fixed[] = {28961,   // 第0段斜率(示例值,需替換為Python輸出)13230,   // 第1段斜率// ... 其他分段的k值146      // 最后一段斜率
};const int32_t b_fixed[] = {0,       // 第0段截距(示例值,需替換為Python輸出)-15731,  // 第1段截距// ... 其他分段的b值196602   // 最后一段截距
};
4.2. 實現分段查找函數

根據輸入 x(0~4095),找到對應的分段索引(即使用哪組 k 和 b):

/*** 查找x所屬的分段索引* 參數:x - 輸入值(0~4095)* 返回:分段索引(0 ~ num_segments-1)*/
static uint8_t find_segment(uint16_t x) {// 遍歷分段點,找到x所在的區間for (uint8_t i = 0; i < num_segments; i++) {if (x >= segment_points[i] && x <= segment_points[i + 1]) {return i;}}return num_segments - 1;  // 兜底(x=4095)
}
4.3. 實現 log10 近似計算函數

利用找到的分段參數(k 和 b),通過定點數運算計算 log10 (x) 的近似值:

/*** 計算log10(x)的近似值(定點數輸出)* 參數:x - 輸入值(0~4095,整數)* 返回:log10(x)的定點數表示(精度:FRACTIONAL_BITS位小數)*/
int32_t log10_approx(uint16_t x) {if (x == 0) {return 0;  // 特殊處理x=0(log10(0)無定義,返回0)}// 1. 查找x所屬的分段uint8_t seg_idx = find_segment(x);  // 或使用find_segment_fast// 2. 取出該分段的k和b(定點數)int32_t k = k_fixed[seg_idx];int32_t b = b_fixed[seg_idx];// 3. 定點數運算:y = k * x + b(需處理小數位對齊)// x是整數,先轉換為定點數(x << FRACTIONAL_BITS)int64_t x_fixed = (int64_t)x << FRACTIONAL_BITS;  // 擴展為64位避免乘法溢出// 計算k * x:結果小數位為FRACTIONAL_BITS*2,右移FRACTIONAL_BITS位對齊int64_t product = (k * x_fixed) >> FRACTIONAL_BITS;// 加上截距b(已為定點數,直接相加)int64_t y_fixed = product + b;// 4. 截斷為32位(防止溢出)if (y_fixed > INT32_MAX) {return INT32_MAX;} else if (y_fixed < INT32_MIN) {return INT32_MIN;} else {return (int32_t)y_fixed;}
}
4.4. (可選)定點數轉浮點數

若需要將結果轉換為浮點數(如用于顯示或上層計算):

/*** 將定點數結果轉換為浮點數* 參數:fixed_val - log10_approx返回的定點數* 返回:對應的浮點數*/
float fixed_to_float(int32_t fixed_val) {return (float)fixed_val / SCALE_FACTOR;
}

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

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

相關文章

qt系統--事件

文章目錄qt系統事件處理鼠標事件鼠標移動事件處理鍵盤事件定時器事件窗口移動和大小改變事件結語很高興和大家見面&#xff0c;給生活加點impetus&#xff01;&#xff01;開啟今天的編程之路&#xff01;&#xff01; 作者&#xff1a;?( ‘ω’ )?260 我的專欄&#xff1a…

Linux機器可直接使用的自動化編譯文件

還在為了Linux機器上一遍遍輸入編譯指令苦惱嗎&#xff1f;你需要make指令以及自己的makefile文件&#xff01;在makefile中寫入自己的個性化指令&#xff0c;讓編譯速度飛起&#xff0c;支持多文件編譯一下文件為個人應用&#xff0c;可以直接cp到相應項目的目錄&#xff0c;每…

Linux學習-數據結構(哈希表)

1.哈希表1.哈希算法將數據通過哈希算法映射成一個關鍵值&#xff0c;存放都在同一位置實現數據的高效存儲和查找&#xff0c;將時間復雜度盡可能降低至O&#xff08;1&#xff09;2.哈希碰撞多個數據通過哈希算法得到的鍵值相同&#xff0c;稱為產生哈希碰撞3.哈希表構建哈希表…

Google Chrome <139.0.7236.0 UAF漏洞

【高危】Google Chrome <139.0.7236.0 UAF漏洞 漏洞描述 Google Chrome 是美國谷歌&#xff08;Google&#xff09;公司的一款Web瀏覽器。 受影響版本中&#xff0c;OpenscreenSessionHost::ReportAndLogError 方法的參數使用了 std::string_view 類型來接收錯誤消息。當一…

CentOS8 Stream 網卡配置及重啟

在 CentOS 8 Stream 中&#xff0c;網卡配置已由 NetworkManager 管理&#xff0c;傳統的 ifcfg-eth0 文件仍然支持&#xff0c;但推薦使用 nmcli 或 nmtui 工具進行網絡配置和管理。以下是網卡配置及重啟的詳細步驟&#xff1a;1. 查看當前網卡狀態列出所有網卡bash復制nmcli …

SpringMvc的原理深度剖析及源碼解讀

一、springmvc啟動加載流程1、引入spring-web.jar包時&#xff0c;在這個包的META-INF/services/javax.servlet.ServletContainerInitializer文件中定義的加載類SpringServletContainerInitializer,提供給springmvc實現初始化的操作。2、在SpringServletContainerInitializer類…

【ESP32-menuconfig(1) -- Build Type及Bootloader config】

Build Type Bootloader configmenuconfig介紹Build typeCONFIG_APP_BUILD_TYPECONFIG_APP_BUILD_TYPE_PURE_RAM_APPCONFIG_APP_REPRODUCIBLE_BUILDCONFIG_APP_NO_BLOBSCONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERSCONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERSBootloader config…

C++信息學奧賽一本通-第一部分-基礎一-第3章-第1節

C信息學奧賽一本通-第一部分-基礎一-第3章-第1節 2051 偶數 #include <iostream>using namespace std;int main() {int number; cin >> number;if (number % 2 0) {cout << "yes";} }2052 范圍判斷 #include <iostream>using namespace std…

自由學習記錄(79)

PBRBRDF原理&Unity實現深入淺出_嗶哩嗶哩_bilibili 進行改進 一個像素點對應一個范圍內的 一個微表面--一個由無數個起起伏伏的結構組成的物理結構 屏幕上的每一個像素點&#xff0c;在渲染時通常會被視為一個“微表面”的代表 比如在這個圖中&#xff0c;只關心紅色的區…

復雜路況誤報率↓78%!陌訊輕量化模型在車輛違停識別的邊緣計算優化?

一、行業痛點&#xff1a;動態交通場景的識別困境據《2024中國智慧交通白皮書》統計&#xff0c;城市核心路段違停誤報率高達35%&#xff0c;主要源于兩大難點&#xff1a;??短暫停靠干擾??&#xff1a;出租車臨時停靠與違停行為特征重疊??復雜背景干擾??&#xff1a;樹…

大語言模型提示工程與應用:提示詞基礎使用方式

提示詞使用方式 學習目標 在本課程中&#xff0c;我們將學習更多關于提示詞使用方式。 相關知識點 提示詞使用 學習內容 1 提示詞使用 1.1 文本摘要 語言模型最典型的應用場景之一就是文本摘要。我們可以通過以下提示實現基礎摘要功能&#xff1a; 提示: 解釋抗生素是什么回答&…

常見命令-資源查看-iostat命令實踐

文章目錄 系統中未安裝 iostat 命令 1. 監控CPU與磁盤的基礎負載 2. 診斷I/O性能瓶頸 3. 實時監控與動態采樣 4. 特定設備或分區的精細化監控 5. 性能測試與基準數據生成 6. 結合其他工具進行綜合調優 總結 結果輸出速查表 第一部分:CPU統計信息 第二部分:設備/磁盤統計信息(…

WinForm 實戰 (進度條):用 ProgressBar+Timer 打造動態進度展示功能

目錄 核心控件解析? ProgressBar 進度條? Timer 定時器? 實戰案例 常見應用場景? 總結? 在 WinForm 桌面應用開發中&#xff0c;進度反饋是提升用戶體驗的關鍵環節。無論是文件處理、數據加載還是復雜計算&#xff0c;一個直觀的進度條能讓用戶清晰了解任務狀態&…

使用 ast-grep 精準匹配指定類的方法調用(以 Java 為例)

使用 ast-grep 精準匹配指定類的方法調用&#xff08;以 Java 為例&#xff09; 在代碼重構、安全審計或靜態分析的場景中&#xff0c;我們常常需要匹配某個特定類中定義的方法調用。而 ast-grep 作為一款基于語法樹的代碼搜索工具&#xff0c;提供了強大的模式匹配功能&#…

Dijkstra?spfa?SPstra?

帶負權的無負環最短路問題 對于一張有負邊權的圖&#xff0c;普通 Dijkstra 就不能用了&#xff0c;比如&#xff1a;正常的 Dijkstra 擴散的節點依次為 1,3,2,41,3,2,41,3,2,4。 這時候可以發現&#xff0c;當點 222 擴散的時候&#xff0c;原本達到點 333 的路徑長度是 111&a…

React函數組件靈魂搭檔:useEffect深度通關指南!

你以為它只是替代componentDidMount&#xff1f;數據抓取、事件綁定、定時清理...&#xff1f;事實上&#xff0c;useEffect才是函數組件的“幕后操控者”&#xff01;但依賴數組的坑、閉包的陷阱&#xff0c;你真的玩轉了嗎&#xff1f; 告別“能用就行”&#xff0c;今天帶你…

LabVIEW實驗室測試框架

在實驗室測試場景中&#xff0c;選用合適的 LabVIEW 框架能夠極大提升測試效率、優化測試流程并保障測試結果的準確性。介紹幾款常用且功能強大的 LabVIEW 測試框架&#xff1a;?TestStand?框架概述?TestStand 是 NI 公司專為測試系統開發設計的一款測試執行管理框架。它能夠…

Kiro :從“規范”到“實現”的全流程 AI 助手

為什么是 Kiro Kiro 是一款面向“規范驅動開發”&#xff08;Spec-Driven Development&#xff09;的 AI 開發助手。與只在“寫代碼”環節輔助不同&#xff0c;Kiro 將“從需求到設計再到實現”的完整鏈路顯性化&#xff0c;把需求、設計、任務分解、代碼與測試、文檔等全部納…

【0基礎PS】PS工具詳解--矩形工具

目錄前言一、矩形工具的基礎認知?二、矩形工具的選項欄詳解?三、矩形工具的繪制技巧?四、矩形工具的實際應用場景?五、常見問題與解決方案?總結前言 在 Photoshop&#xff08;簡稱 PS&#xff09;的眾多繪圖工具中&#xff0c;矩形工具是使用率極高的基礎工具之一。無論是…

移動端app專項測試

學習目標&#xff1a;app專項測試知識點&#xff0c;其他知識擴充一、app專項&#xff08;app怎么測試/app側重點在哪&#xff09;1.功能&#xff1a;跟前面功能測試一樣&#xff08;跟需求文檔提取測試點&#xff0c;編寫測試用例&#xff09;2.安裝1.不同品牌安裝,不同操作系…