《编写高质量代码:改善c程序代码的125个建议》——建议12-1:用倒数相乘来实现除法运算

简介:

本节书摘来自华章计算机《编写高质量代码:改善c程序代码的125个建议》一书中的第2章,建议12-1,作者:马 伟 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

建议12-1:用倒数相乘来实现除法运算

何为倒数相乘?其实很简单,它的核心思想就是利用乘法来代替实现除法运算。例如,在IA-32处理器中,乘法指令的运算速度比除法指令要快4~6倍。因此,在某些情况下尽量使用乘法指令来代替除法指令。
那么,我们该如何利用乘法来代替实现除法运算呢?原理就是被除数乘以除数的倒数,用公式表现为:

x/y=x*(1/y)

例如,计算10/5,可以根据公式x/y=x*(1/y)这样来计算:

10/5=10*(1/5)=10*0.2=2

在实际应用中,一些编译器也正是基于这个原理才得以将除法运算转换为乘法运算的。现在我们来看一个除法运算示例,如代码清单2-1所示。

代码清单2-1 除法运算示例
#include <stdio.h>
int main(void)
{
    int x = 3/2;
    float y = 3.0/2.0;
    printf("3/2 = %d\r\n3.0/2.0 = %1.1f\n",x,y);
    return 0;
}

代码清单2-1的运行结果如图2-1所示。


1347618f15d71dfa60ed947aa0cc5ad08d8f7494

通过代码清单2-1可以看出,很明显没能充分考虑到浮点类型。另外,在C语言中,一般情况下1除以任何数其结果皆为0。那么怎样才能解决这个问题呢?编译器采用了一种称为“定点运算”(fixed-point arithmetic)的
方法。
那么何为定点运算,定点运算有什么特点呢?
前面已经阐述过,由于计算机表示实数时为了在固定位数内能表示尽量精确的实数值,分配给表示小数部分的位数并不是固定的,也就是说“小数点是浮动的”,因此计算机表示的实数数据类型也称为浮点数。
相对于“小数点是浮动的”来讲,定点运算根据字面意思来理解就是“小数点是固定的”。有了定点运算,表示小数时不再用阶码(exponent component,即小数点在浮点数据类型中的位置),而是要保持小数点的位置固定不变。这和硬件浮点数机制截然不同,硬件浮点数机制是由硬件负责向整数部分和小数部分分配可用的位数。有了这种机制,浮点数就可以表示很大范围的数——从极小的数(在0~1的实数)到极大的数(在小数点前有数十个0)。这种小数的定点表示法有很多优点,尤其能极大地提高效率。当然,作为代价,同样也必须承受随之而来的精度上的损失。
对于定点数表示法(fixed-point),相信大家并不陌生。所谓定点格式,即约定机器中所有数据的小数点位置是固定不变的。在计算机中通常采用两种简单的约定:将小数点的位置固定在数据的最高位之前(即定点小数),或者固定在最低位之后(即定点整数)。
其中,定点小数是纯小数,约定的小数点位置在符号位之后、有效数值部分的最高位之前。若数据x的形式为x=x0x1x2…xn(其中x0为符号位,x1,…,xn是数值的有效部分,也称为尾数,x1为最高有效位),则在计算机中的表示形式为:

4acb2541aff1e471e2a7b79f5522fd9cc3fbe239

一般说来,如果最末位xn=1,前面各位都为0,则数的绝对值最小,即|x|min=2-n;如果各位均为 1,则数的绝对值最大,即|x|max = 1-2-n。因此定点小数的表示范围是:
2-n≤|x|≤1-2-n

定点整数是纯整数,约定的小数点位置在有效数值部分最低位之后。若数据x的形式为x = x0x1x2…xn(其中x0为符号位,x1,…,xn是尾数,xn为最低有效位),则在计算机中的表示形式为:


<a href=https://yqfile.alicdn.com/baf6213179facf697a3ec8d28a953eccf2215f66.png" >

由此可知,定点整数的表示范围是:
1≤|x|≤2n-1

当数据小于定点数能表示的最小值时,计算机将它作0处理,称为下溢;当数据大于定点数能表示的最大值时,计算机将无法表示,称为上溢,上溢和下溢统称为溢出。
当计算机采用定点数表示时,对于既有整数又有小数的原始数据,需要设定一个比例因子,数据按该比例缩小成定点小数或扩大成定点整数再参加运算。在运算结果中,根据比例因子,将数据还原成实际数值。若比例因子选择不当,往往会使运算结果产生溢出或降低数据的有效精度。

相关文章
|
4月前
|
机器学习/深度学习 算法 安全
【图像识别】手掌纹理识别(Matlab代码实现)
【图像识别】手掌纹理识别(Matlab代码实现)
209 0
|
8月前
|
存储 JSON API
aipy实战:Deepseek-V3、Hunyuan&Qwen分析618平板攻略
Aipy是一款结合LLM与Python的智能工具,用户通过简单指令即可让LLM分析并生成代码,实时解决问题。本次v0.1.28版本新增联网搜索、案例分享等功能,并引入混元和Qwen模型。测评中,三个模型完成“618平板选购攻略”任务表现各异:deepseek-v3界面精美、信息全面但价格有偏差;hunyuan-turbos-latest信息不全但界面简洁;qwen-plus-latest推荐合理但数据失真。总体而言,Aipy在操作友好性和分析界面上显著提升,适合解决实际问题。
|
机器学习/深度学习 PyTorch 算法框架/工具
空间金字塔池化(Spatial Pyramid Pooling, SPP)原理和代码实现(Pytorch)
想直接看公式的可跳至第三节 3.公式修正 一、为什么需要SPP 首先需要知道为什么会需要SPP。 我们都知道卷积神经网络(CNN)由卷积层和全连接层组成,其中卷积层对于输入数据的大小并没有要求,唯一对数据大小有要求的则是第一个全连接层,因此基本上所有的CNN都要求输入数据固定大小,例如著名的VGG模型则要求输入数据大小是 (224*224) 。
2518 0
|
7月前
|
PyTorch 算法框架/工具 C++
人工智能算法python程序运行环境安装步骤整理
本教程详细介绍Python与AI开发环境的配置步骤,涵盖软件下载、VS2017安装、Anaconda配置、PyCharm设置及组件安装等内容,适用于Windows系统,助你快速搭建开发环境。
|
机器学习/深度学习 缓存 人工智能
【AI系统】QNNPack 算法
QNNPACK是Marat Dukhan开发的量化神经网络计算加速库,专为移动端优化,性能卓越。本文介绍QNNPACK的实现,包括间接卷积算法、内存重排和间接缓冲区等关键技术,有效解决了传统Im2Col+GEMM方法存在的空间消耗大、缓存效率低等问题,显著提升了量化神经网络的计算效率。
340 6
【AI系统】QNNPack 算法
|
机器学习/深度学习 人工智能 自然语言处理
NVIDIA Triton系列13-用 FasterTransformer 和 Triton 加速大型 Transformer 模型的推理
本文介绍了 NVIDIA FasterTransformer 库及其在加速大型 Transformer 模型推理中的应用。FasterTransformer 是一个高效、可扩展的库,支持分布式多 GPU 推理,特别适合处理具有数万亿参数的模型。文章还详细讲解了如何使用 FasterTransformer 和 NVIDIA Triton 推理服务器优化 GPT-J 和 T5 模型的推理性能,包括张量并行、流水线并行等技术。
555 0
NVIDIA Triton系列13-用 FasterTransformer 和 Triton 加速大型 Transformer 模型的推理
|
缓存 监控 Linux
Linux配置成代理服务器
代理服务器(Proxy Server)是一种位于计算机网络中的中间服务器,它充当了客户端和目标服务器之间的中介,用于转发客户端请求并获取目标服务器的响应。代理服务器的主要功能包括以下几点:
7712 1
|
机器学习/深度学习 人工智能 算法
【AI伦理与社会责任】讨论人工智能在隐私保护、偏见消除、自动化对就业的影响等伦理和社会问题。
人工智能(AI)作为第四次产业革命的核心技术,在推动社会进步和经济发展的同时,也引发了一系列伦理和社会问题。以下从隐私保护、偏见消除以及自动化对就业的影响三个方面进行详细讨论。
626 2
|
存储 关系型数据库 PostgreSQL
PostgreSQL有何特点?
【8月更文挑战第5天】PostgreSQL有何特点?
681 6
|
Prometheus 监控 Cloud Native
Java一分钟之-Micrometer:应用指标库
【6月更文挑战第11天】Micrometer是Java应用的度量库,提供统一API与多监控系统集成,如Prometheus、InfluxDB。它有标准化接口、广泛后端支持、自动配置和多种度量类型。常见问题包括度量命名不规范、数据过载和忽略维度。解决办法包括遵循命名规范、选择重要指标和使用标签。了解API、设计度量策略和选好监控系统是关键。通过正确使用Micrometer,可建立高效监控体系,保障应用稳定性和性能。
462 1