【学Rust写CAD】15 定点数实现(fixed.rs)

ops/2025/4/2 3:45:54/

源代码

fixed.rs文件实现了一个定点数(Fixed Point)类型 Fixed,用于在整数运算中模拟小数运算。代码如下:

rust">//小数位数
const FIXED_FRACTION_BITS: u32 = 16;
//用于 双线性插值(Bilinear Interpolation) 的计算,它决定了插值权重(weight)的精度位数。一般为4或8
const BILINEAR_INTERPOLATION_BITS: u32 = 4;#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Fixed(i32);impl Fixed {pub const ONE: Fixed = Fixed(1 << FIXED_FRACTION_BITS);pub const HALF: Fixed = Fixed(1 << (FIXED_FRACTION_BITS-1));//FIXED_ONE/// 创建新的Fixed值pub fn new(value: i32) -> Self {Fixed(value)}/// 将浮点数转换为定点数pub fn from_float(x: f32) -> Self {Fixed(((x * (1 << FIXED_FRACTION_BITS) as f32) + 0.5) as i32)}/// 将定点数转换为整数(截断小数部分)pub fn to_int(self) -> i32 {self.0 >> FIXED_FRACTION_BITS}/// 获取双线性插值权重pub fn bilinear_weight(self) -> u32 {// 丢弃不需要的精度位let reduced = self.0 >> (FIXED_FRACTION_BITS - BILINEAR_INTERPOLATION_BITS);// 提取剩余的小数部分let fraction = reduced & ((1 << BILINEAR_INTERPOLATION_BITS) - 1);fraction as u32}/// 获取内部值pub fn raw_value(self) -> i32 {self.0}
}// 实现一些运算符重载以便更方便地使用
impl std::ops::Add for Fixed {type Output = Self;fn add(self, rhs: Self) -> Self {Fixed(self.0 + rhs.0)}
}impl std::ops::Sub for Fixed {type Output = Self;fn sub(self, rhs: Self) -> Self {Fixed(self.0 - rhs.0)}
}impl std::ops::Mul for Fixed {type Output = Self;fn mul(self, rhs: Self) -> Self {// 定点数乘法需要调整小数位Fixed((self.0 as i64 * rhs.0 as i64 >> FIXED_FRACTION_BITS) as i32)}
}impl std::ops::Div for Fixed {type Output = Self;fn div(self, rhs: Self) -> Self {// 定点数除法需要调整小数位Fixed(((self.0 as i64 << FIXED_FRACTION_BITS) / rhs.0 as i64) as i32)}
}impl std::ops::Shr<u32> for Fixed {type Output = Self;fn shr(self, rhs: u32) -> Self {Fixed(self.0 >> rhs)}
}impl std::ops::Shl<u32> for Fixed {type Output = Self;fn shl(self, rhs: u32) -> Self {Fixed(self.0 << rhs)}
}

代码解析:

常量定义
  1. FIXED_FRACTION_BITS: u32 = 16:
  • 表示小数部分占用的位数

  • 使用16位表示小数部分,意味着有16位小数和16位整数(在i32中)

  1. BILINEAR_INTERPOLATION_BITS: u32 = 4:
  • 用于双线性插值计算的精度位数

  • 通常设置为4或8位,决定了插值权重的精度

Fixed 结构体

Fixed 是一个包装了 i32 的新类型,用于表示定点数。

重要常量
  1. ONE: 表示定点数1.0,值为 1 << 16 (65536)

  2. HALF: 表示定点数0.5,值为 1 << 15 (32768)

主要方法
  1. new(value: i32): 直接从一个i32值创建Fixed数

  2. from_float(x: f32): 将浮点数转换为定点数

  • 公式:x * (1 << 16) + 0.5 (0.5用于四舍五入)
  1. to_int(): 将定点数转换为整数(截断小数部分)
  • 右移16位丢弃小数部分
  1. bilinear_weight(): 获取双线性插值权重
  • 先丢弃不需要的精度位(保留BILINEAR_INTERPOLATION_BITS位)

  • 然后提取剩余的小数部分作为权重

  1. raw_value(): 获取内部存储的原始i32值
运算符重载

实现了基本的算术运算,注意乘法和除法的特殊处理:

  1. 乘法:
  • 需要先将操作数扩展为i64防止溢出

  • 结果右移16位调整小数位

  1. 除法:
  • 被除数左移16位扩展

  • 然后进行除法运算

定点数表示原理

这个实现使用Q16.16格式的定点数:

  • 32位整数(i32)中,高16位表示整数部分,低16位表示小数部分

  • 例如:0x00010000 表示1.0 (1 << 16)

  • 例如:0x00008000 表示0.5 (1 << 15)

应用场景

这种定点数实现常用于:

  1. 需要高性能小数运算但不想用浮点数的场合

  2. 图形处理中的坐标计算

  3. 嵌入式系统等不支持浮点运算硬件的环境

  4. 双线性插值等需要精确控制精度的算法

双线性插值中使用时,bilinear_weight()方法提供了权重计算,通过控制BILINEAR_INTERPOLATION_BITS可以调整插值精度。

文章来源:https://blog.csdn.net/weixin_43219667/article/details/146582741
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ppmy.cn/ops/170896.html

相关文章

Spring Cloud ReactorServiceInstanceLoadBalancer 自定义负载均衡

自定义负载均衡类 import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.ObjectProvider; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client…

新能源智慧灯杆是否支持新能源汽车充电功能?

哇哦&#xff01;你是否想象过&#xff0c;在街头巷尾普通的灯杆&#xff0c;竟能摇身一变&#xff0c;成为为新能源汽车充电的强大能量站&#xff1f;没错&#xff0c;这就是叁仟新能源智慧灯杆&#xff01;它不仅外观时尚&#xff0c;更具备超厉害的新能源汽车充电功能&#…

基于聚类与引力斥力优化的选址算法

在众多实际场景中&#xff0c;诸如消防设施选址、基站布局规划以及充电桩站点部署等&#xff0c;都面临着如何利用最少的资源&#xff0c;实现对所有目标对象全面覆盖的难题。为有效解决这类问题&#xff0c;本文提出一种全新的组合算法模型 —— 基于聚类与引力斥力优化的选址…

VScode配置默认终端为Anaconda Prompt

VScode配置默认终端为Anaconda Prompt 1 Linux系统 VSCode入门操作| 配置anaconda终端完整顺畅版 1 Linux系统 &#xff08;1&#xff09; 打开 VSCode&#xff0c;按 Ctrl , 或点击左下角齿轮图标&#xff0c;选择 设置。 &#xff08;2&#xff09;搜索 terminal.integrate…

微服务架构中的服务发现与 Consul 实践

在微服务架构中&#xff0c;服务之间的通信是核心问题之一。随着服务数量的增长&#xff0c;如何高效地管理和定位服务实例变得尤为重要。本文将介绍服务发现的基本概念&#xff0c;并详细讲解如何使用 Consul 进行服务注册、发现和健康检查。 1. 什么是服务发现&#xff1f; …

企业级全栈开发终极指南:Spring Boot+Vue3+Kubernetes实战,从0到上线高并发系统

简介 本文以电商系统为例,完整呈现从需求分析到上线运维的企业级开发全流程。包含12个关键步骤、30+代码示例、5个架构设计图,以及完整的Docker/Kubernetes部署方案。所有代码均符合企业级规范,可直接用于生产环境。 企业级开发的终极挑战 行业痛点: 90%的开发者在企业级…

太阳能台风预警宣传信号智慧杆:科技赋能防灾减灾的新标杆

在全球气候变化持续加剧、台风灾害频繁发生的大背景之下&#xff0c;借助科技手段提高预警效率以及保障公共安全&#xff0c;已然成为现代城市管理领域的关键课题。太阳能台风预警宣传信号智慧杆&#xff08;以下简称 “智慧杆”&#xff09;适时出现&#xff0c;凭借其以绿色能…

SQL-查询漏洞

一、查询注入的数据类型 //list.php<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatiable" content"IEedge"><meta name"viewport" content&…