【C语言标准库函数】浮点数分解与构造: frexp() 和 ldexp()
目录
一、头文件
二、函数简介
2.1. frexp(double x, int *exp)
2.2. ldexp(double x, int exp)
三、函数实现(概念性)
3.1. frexp 的概念性实现
3.2. ldexp 的概念性实现
四、注意事项
五、示例代码
在C语言标准库中,frexp() 和 ldexp() 是两个与浮点数表示相关的函数,它们分别用于将浮点数分解为尾数和指数的形式,以及从尾数和指数构造浮点数。这两个函数都定义在 <math.h> 头文件中。
一、头文件
这两个函数都定义在<math.h>头文件中。要使用它们,需要在C程序中包含这个头文件。
二、函数简介
2.1. frexp(double x, int *exp)
功能:frexp函数用于将浮点数x分解为尾数(mantissa)和指数(exponent)的乘积形式,即x = mantissa * 2^exp。这种分解方式在浮点数的表示和计算中非常有用,尤其是在需要处理浮点数范围或精度问题时。
参数:
double x:要分解的浮点数。int *exp:指向整数的指针,用于存储分解得到的指数部分。
返回值:返回类型为double,表示分解得到的尾数部分。尾数的绝对值通常在[0.5, 1)范围内,但有一个特殊情况需要注意:如果x是0,则尾数也是0,且指数也是0(尽管标准可能允许指数未定义,但大多数实现会将其设为0)。如果x是负数,则尾数也是负数,但其绝对值仍然在[0.5, 1)范围内(或者在某些实现中,可能是[0, 0.5)并带有负号,但这种情况较少见)。
注意点:
- 尾数的符号与
x的符号相同。 - 指数
exp是一个整数,表示2的幂次,用于与尾数相乘以恢复原始浮点数。 - 分解是唯一的,除了
x为0的情况外。
2.2. ldexp(double x, int exp)
功能:ldexp函数用于根据给定的尾数x和指数exp构造浮点数,即返回x * 2^exp。这个函数是frexp的逆操作,用于将尾数和指数组合回原始的浮点数形式。
参数:
double x:尾数部分。int exp:指数部分,表示2的幂次。
返回值:返回类型为double,表示根据尾数和指数构造的浮点数。
注意点:
- 如果
x是0,则无论exp的值是多少,结果都是0。 - 如果
x和exp的组合超出了浮点数的表示范围(即上溢或下溢),则结果可能是无穷大(INFINITY)、负无穷大(-INFINITY)或不是一个数(NaN)。 ldexp函数提供了一种方便的方式来调整浮点数的范围,而不需要直接操作浮点数的位表示。
三、函数实现(概念性)
虽然我们不能直接看到frexp和ldexp的标准库实现,但我们可以根据它们的定义来构想一个概念性的实现。请注意,实际的库实现可能会使用更复杂的算法来优化性能和精度。
3.1. frexp 的概念性实现
frexp的核心思想是将浮点数x分解为m * 2^e,其中m(尾数)的绝对值在[0.5, 1)(或[0, 0.5)对于负数,取决于具体实现)范围内,e(指数)是一个整数。
在C语言中,我们可以通过位操作来模拟这个过程,但考虑到C标准库已经提供了足够的工具来处理浮点数,我们可以使用这些工具来构造一个更高级的伪代码。
#include <math.h>
#include <stdio.h> // 伪代码,非实际可编译代码
double frexp_pseudo(double x, int *exp) { // 处理特殊情况 if (x == 0.0) { *exp = 0; return 0.0; } // 获取x的符号 int sign = (x < 0) ? -1 : 1; // 取绝对值 x = fabs(x); // 初始化指数 *exp = 0; // 当x不在[0.5, 1)范围内时,不断除以2并调整指数 while (x >= 1.0) { x /= 2.0; (*exp)++; } // 对于某些实现,可能还需要处理x < 0.5的情况 // 这里我们假设只处理[0.5, 1)范围 // 如果原始x是负数,则结果也应该是负数 if (sign < 0) { x = -x; } return x;
} // 注意:上面的伪代码没有处理x < 0.5的情况,实际实现可能会更复杂
3.2. ldexp 的概念性实现
ldexp的实现相对简单,它只需要将尾数乘以2的指数次幂。
#include <math.h> // 伪代码,基于C语言
double ldexp_pseudo(double x, int exp) { // 直接使用pow函数,注意这里pow函数可能会引入浮点误差 // 在实际实现中,可能会使用更高效的算法来避免这种误差 return x * pow(2.0, (double)exp);
} // 注意:虽然这里使用了pow函数,但在实际库中,为了性能和精度,
// ldexp函数可能会使用专门的算法来实现2的幂次乘法。
上面的ldexp_pseudo函数使用了pow函数,这在性能上可能不是最优的,因为pow函数是通用的,而ldexp需要处理的是2的幂次乘法,这可以通过更高效的位操作或查找表来实现。
在实际应用中,我们应该使用标准库提供的frexp和ldexp函数,因为它们经过了优化,能够提供更好的性能和精度。
四、注意事项
- 当
x为0时,frexp返回的尾数是0,指数是未定义的(但通常会设置为0)。 - 浮点数的精度限制意味着这些函数的结果可能不是完全精确的,特别是在极端情况下。
- 在使用这些函数之前,请确保包含了
<math.h>头文件。
五、示例代码
#include <stdio.h>
#include <math.h> int main() { double x = 12.34; int exp; // 使用 frexp 分解浮点数 double mantissa = frexp(x, &exp); printf("Original: %.2f\n", x); printf("Decomposed: mantissa = %.2f, exponent = %d\n", mantissa, exp); // 验证分解结果 double reconstructed = ldexp(mantissa, exp); printf("Reconstructed: %.2f\n", reconstructed); // 尝试0值 x = 0.0; mantissa = frexp(x, &exp); printf("Original (0): %.2f\n", x); printf("Decomposed (0): mantissa = %.2f, exponent = %d\n", mantissa, exp); // 注意:对于0,指数是未定义的,但通常设置为0 // 尝试使用ldexp重新构造0 reconstructed = ldexp(mantissa, exp); printf("Reconstructed (0): %.2f\n", reconstructed); return 0;
}

在这个示例中,我们首先使用frexp()函数将浮点数12.34分解为尾数和指数,并通过ldexp()函数使用这些值重新构造原始浮点数,以验证分解的正确性。然后,尝试对0.0进行相同的操作,并注意到当x为0时,尾数是0,而指数是未定义的(但在这个例子中,它被设置为0)。最后,我们使用ldexp()重新构造0,以展示即使指数是未定义的,该函数也能正确处理这种情况(尽管在这种情况下,结果显然是已知的)。
相关文章:
【C语言标准库函数】浮点数分解与构造: frexp() 和 ldexp()
目录 一、头文件 二、函数简介 2.1. frexp(double x, int *exp) 2.2. ldexp(double x, int exp) 三、函数实现(概念性) 3.1. frexp 的概念性实现 3.2. ldexp 的概念性实现 四、注意事项 五、示例代码 在C语言标准库中,frexp() 和 ld…...
【Git】tortoisegit使用配置
1. 安装 首先下载小乌龟,下载地址:https://tortoisegit.org/download/, 可以顺便下载语言包! 安装时,默认安装就可以,一路next。也可以安装到指定目录中 目前已完成本地安装,接下来就需要与远程仓库建立连接&…...
Spring基于文心一言API使用的大模型
有时做项目我们可能会遇到要在项目中对接AI大模型 本篇文章是对使用文心一言大模型的使用总结 前置任务 在百度智能云开放平台中注册成为开发者 百度智能云开放平台 进入百度智能云官网进行登录,点击立即体验 点击千帆大模型平台 向下滑动,进入到模型…...
运维_Mac环境单体服务Docker部署实战手册
Docker部署 本小节,讲解如何将前端 后端项目,使用 Docker 容器,部署到 dev 开发环境下的一台 Mac 电脑上。 1 环境准备 需要安装如下环境: Docker:容器MySQL:数据库Redis:缓存Nginx&#x…...
[论文笔记] Deepseek-R1R1-zero技术报告阅读
启发: 1、SFT&RL的训练数据使用CoT输出的格式,先思考再回答,大大提升模型的数学与推理能力。 2、RL训练使用群体相对策略优化(GRPO),奖励模型是规则驱动,准确性奖励和格式化奖励。 1. 总体概述 背景与目标 报告聚焦于利用强化学习(RL)提升大型语言模型(LLMs)…...
Centos Ollama + Deepseek-r1+Chatbox运行环境搭建
Centos Ollama Deepseek-r1Chatbox运行环境搭建 内容介绍下载ollama在Ollama运行DeepSeek-r1模型使用chatbox连接ollama api 内容介绍 你好! 这篇文章简单讲述一下如何在linux环境搭建 Ollama Deepseek-r1。并在本地安装的Chatbox中进行远程调用 下载ollama 登…...
一文读懂:TCP网络拥塞的应对策略与方案
TCP(传输控制协议)是互联网中广泛使用的可靠传输协议,它通过序列号、确认应答、重发控制、连接管理以及窗口控制等机制确保数据的可靠传输。然而,在网络环境中,由于多个主机共享网络资源,网络拥塞成为了一个…...
SpringSecurity:授权服务器与客户端应用(入门案例)
文章目录 一、需求概述二、开发授权服务器1、pom依赖2、yml配置3、启动服务端 三、开发客户端应用1、pom依赖2、yml配置3、SecurityConfig4、接口5、测试 一、需求概述 maven需要3.6.0以上版本 二、开发授权服务器 1、pom依赖 <dependency><groupId>org.springfr…...
Python与java的区别
一开始接触Python的时候,哔哩视频铺天盖地,看了很多人主讲的,要找适合自己口味的,各种培训机构喜欢在各种平台引流打广告,看了很多家,要么就是一个视频几个小时,长篇大论不讲原理只讲应用&#…...
doris:MySQL 兼容性
Doris 高度兼容 MySQL 语法,支持标准 SQL。但是 Doris 与 MySQL 还是有很多不同的地方,下面给出了它们的差异点介绍。 数据类型 数字类型 类型MySQLDorisBoolean- 支持 - 范围:0 代表 false,1 代表 true- 支持 - 关键字&am…...
SQL中 的exists用法
EXISTS 是 SQL 中的一个子查询条件,用于检查子查询是否返回任何行。如果子查询返回至少一行,则 EXISTS 返回 TRUE。 例如,查询有订单的客户列表: SELECT * FROM customers c WHERE EXISTS (SELECT 1 FROM orders o WHERE o.cust…...
案例1.spark和flink分别实现作业配置动态更新案例
目录 目录 一、背景 二、解决 1.方法1:spark broadcast广播变量 a. 思路 b. 案例 ① 需求 ② 数据 ③ 代码 2.方法2:flink RichSourceFunction a. 思路 b. 案例 ① 需求 ② 数据 ③ 代码 ④ 测试验证 测试1 测试2 测试3 一、背景 在实时作业(如 Spark Str…...
大数据学习之SparkSql
95.SPARKSQL_简介 网址: https://spark.apache.org/sql/ Spark SQL 是 Spark 的一个模块,用于处理 结构化的数据 。 SparkSQL 特点 1 易整合 无缝的整合了 SQL 查询和 Spark 编程,随时用 SQL 或 DataFrame API 处理结构化数据。并且支…...
鸿蒙UI(ArkUI-方舟UI框架)- 使用文本
返回主章节 → 鸿蒙UI(ArkUI-方舟UI框架) 文本使用 文本显示 (Text/Span) Text是文本组件,通常用于展示用户视图,如显示文章的文字内容。Span则用于呈现显示行内文本。 创建文本 string字符串 Text("我是一段文本"…...
Spider 数据集上实现nlp2sql训练任务
NLP2SQL(自然语言处理到 SQL 查询的转换)是一个重要的自然语言处理(NLP)任务,其目标是将用户的自然语言问题转换为相应的 SQL 查询。这一任务在许多场景下具有广泛的应用,尤其是在与数据库交互的场景中&…...
数据结构——【树模板】
#思路 1、 结点类: 属性:数据,孩子结点列表 功能1:认孩子: 前提:在父子都是结点的情况下 2. 树类: 属性:根节点,生成初始化的总结点 功能1:获取初始化…...
R 数组:高效数据处理的基础
R 数组:高效数据处理的基础 引言 在数据科学和统计分析领域,R 语言以其强大的数据处理和分析能力而备受推崇。R 数组是 R 语言中用于存储和操作数据的基本数据结构。本文将详细介绍 R 数组的创建、操作和优化,帮助读者掌握 R 数组的使用技巧…...
【DeepSeek】DeepSeek概述 | 本地部署deepseek
目录 1 -> 概述 1.1 -> 技术特点 1.2 -> 模型发布 1.3 -> 应用领域 1.4 -> 优势与影响 2 -> 本地部署 2.1 -> 安装ollama 2.2 -> 部署deepseek-r1模型 1 -> 概述 DeepSeek是由中国的深度求索公司开发的一系列人工智能模型,以其…...
npm link,lerna,pnmp workspace区别
npm link、Lerna 和 pnpm workspace 是三种不同的工具/功能,用于处理 JavaScript 项目的依赖管理和 Monorepo 场景。它们的核心区别如下: 1. npm link 用途 本地调试依赖:将本地开发的包(Package A)临时链接到另一个…...
ASP.NET Core 使用 WebClient 从 URL 下载
本文使用 ASP .NET Core 3.1,但它在.NET 5、 .NET 6和.NET 8上也同样适用。如果使用较旧的.NET Framework,请参阅本文,不过,变化不大。 如果想要从 URL 下载任何数据类型,请参阅本文:HttpClient 使用WebC…...
【CubeMX-HAL库】STM32F407—无刷电机学习笔记
目录 简介: 学习资料: 跳转目录: 一、工程创建 二、板载LED 三、用户按键 四、蜂鸣器 1.完整IO控制代码 五、TFT彩屏驱动 六、ADC多通道 1.通道确认 2.CubeMX配置 ①开启对应的ADC通道 ②选择规则组通道 ③开启DMA ④开启ADC…...
vue3 点击图标从相册选择二维码图片,并使用jsqr解析二维码(含crypto-js加密解密过程)
vue3 点击图标从相册选择二维码图片,并使用jsqr解析二维码(含crypto-js加密解密过程) 1.安装 jsqr 和 crypto-js npm install -d jsqr npm install crypto-js2.在util目录下新建encryptionHelper.js文件,写加密解密方法。 // e…...
kafka 3.5.0 raft协议安装
前言 最近做项目,需要使用kafka进行通信,且只能使用kafka,笔者没有测试集群,就自己搭建了kafka集群,实际上笔者在很早之前就搭建了,因为当时还是zookeeper(简称ZK)注册元数据&#…...
用Kibana实现Elasticsearch索引的增删改查:实战指南
在大数据时代,Elasticsearch(简称 ES)和 Kibana 作为强大的数据搜索与可视化工具,受到了众多开发者的青睐。Kibana 提供了一个直观的界面,可以方便地对 Elasticsearch 中的数据进行操作。本文将详细介绍如何使用 Kiban…...
Redis基础笔记
一、基础知识 连接方式 CLI (Command Line Interface)API (Application Programming Interface)GUI (Graphical User Interface) 启动 redis-server连接到Redis(Redis CLI Client) redis redis-cli telnet 127.0.0.1 6379退出 quit/exit查看过期时…...
前后端服务配置
1、安装虚拟机(VirtualBox或者vmware),在虚拟机上配置centos(选择你需要的Linux版本),配置如nginx服务器等 1.1 VMware 下载路径Sign In注册下载 1.2 VirtualBox 下载路径https://www.virtualbox.org/wiki/Downloads 2、配置服…...
springboot 事务管理
在Spring Boot中,事务管理是通过Spring框架的事务管理模块来实现的。Spring提供了声明式事务管理和编程式事务管理两种方式。通常,我们使用声明式事务管理,因为它更简洁且易于维护。 1. 声明式事务管理 声明式事务管理是通过注解来实现的。…...
基于Typescript,使用Vite构建融合Vue.js的Babylon.js开发环境
一、创建Vite项目 使用Vite初始化一个VueTypeScript项目: npm create vitelatest my-babylon-app -- --template vue-ts cd my-babylon-app npm create vitelatest my-babylon-app -- --template vue-ts 命令用于快速创建一个基于 Vite 的 Vue TypeScript 项目。…...
在阿里云ECS上一键部署DeepSeek-R1
DeepSeek-R1 是一款开源模型,也提供了 API(接口)调用方式。据 DeepSeek介绍,DeepSeek-R1 后训练阶段大规模使用了强化学习技术,在只有极少标注数据的情况下提升了模型推理能力,该模型性能对标 OpenAl o1 正式版。DeepSeek-R1 推出…...
git SourceTree 使用
Source Tree 使用原理 文件的状态 创建仓库和提交 验证 再克隆的时候发发现一个问题,就是有一个 这个验证,起始很简单 就是 gitee 的账号和密码,但是要搞清楚的是账号不是名称,我之前一直再使用名称登录老是出问题 这个很简单的…...
