将浮点数转换为分数

原理

double 由以下部分组成:

  1. 符号位
  2. 指数部分
  3. 尾数部分
  • 符号位的含义:为 0 表示正数,为 1 表示负数。
  • 指数部分的含义:在规格化数中,指数部分的整型值减去 1023 就是实际的指数值。在非规格化数中,指数恒为 -1022 这个常数。
  • 尾数部分:尾数部分的整型值就是它的值,不像指数部分那样需要分别处理。

规格化数的值:
value = ( − 1 ) sign × 2 exponent − 1023 × ( 1 + mantissa 2 52 ) \text{value} = (-1)^{\text{sign}} \times 2^{\text{exponent} - 1023} \times \left(1 + \frac{\text{mantissa}}{2^{52}}\right) value=(1)sign×2exponent1023×(1+252mantissa)

非规格化数的值:
value = ( − 1 ) sign × 2 − 1022 × ( mantissa 2 52 ) \text{value} = (-1)^{\text{sign}} \times 2^{-1022} \times \left(\frac{\text{mantissa}}{2^{52}}\right) value=(1)sign×21022×(252mantissa)

浮点特殊值

NaN

  • 指数部分所有位都为 1.
  • 尾数部分不为 0.

正无穷、负无穷

  • 指数部分所有位都为 1.
  • 尾数部分所有位都为 0.

则根据符号位来确定是正无穷还是负无穷。符号位为 0 则是正无穷,符号位为 1 则是负无穷。

DoubleBitView

设计一个类,用来解析 double 的位结构

#pragma once
#include "base/bit/bit.h"
#include "base/math/FloatNumberValueType.h"
#include <cstdint>namespace base
{namespace bit{class DoubleBitView{private:union Union{double _double;uint64_t _uint64;};Union _value_union{};public:constexpr DoubleBitView() = default;constexpr DoubleBitView(double value){_value_union._double = value;}constexpr double Value() const{return _value_union._double;}constexpr uint64_t AsUint64() const{return _value_union._uint64;}////// @brief 尾数部分的位。////// @return///constexpr uint64_t MantissaBits() const{return base::bit::ReadBits(_value_union._uint64, 0, 52);}////// @brief 指数部分的位。////// @return///constexpr uint64_t ExponentBits() const{return base::bit::ReadBits(_value_union._uint64, 52, 63);}////// @brief 符号位。////// @return///constexpr bool SignBit() const{return base::bit::ReadBit(_value_union._uint64, 63);}////// @brief 浮点值的类型。////// @return///constexpr base::bit::FloatNumberValueType ValueType() const{if (ExponentBits() == base::bit::ReadBits(UINT64_MAX, 52, 63)){// 指数位全为 1if (MantissaBits() != 0){// 尾数位不全为 0,return base::bit::FloatNumberValueType::NaN;}// 尾数位全为 0if (!SignBit()){// 正无穷return base::bit::FloatNumberValueType::PositiveInfinite;}// 负无穷return base::bit::FloatNumberValueType::NegativeInfinite;}// 指数位不全为 1if (ExponentBits() == 0){// 指数位全为 0return base::bit::FloatNumberValueType::Denormalized;}return base::bit::FloatNumberValueType::Normalized;}////// @brief 是正数。////// @return///constexpr bool Positive() const{// 符号位位 0 则是正数return !SignBit();}////// @brief 是负数。////// @return///constexpr bool Negative() const{// 符号位位 1 则是负数return SignBit();}};} // namespace bit
} // namespace base

分数类

有了 double 的位结构之后,分数类就可以基于它进行构造了

base::Fraction::Fraction(base::Double const &value)
{if (value.Value() == 0.0){SetNum(0);SetDen(1);return;}base::bit::DoubleBitView view{value.Value()};switch (view.ValueType()){case base::bit::FloatNumberValueType::Normalized:{base::Fraction f1 = base::pow(base::BigInteger{2},base::BigInteger{view.ExponentBits() - 1023});base::Fraction f2 = base::Fraction{view.MantissaBits(),base::pow(base::BigInteger{2}, base::BigInteger{52}),};base::Fraction value = f1 * (1 + f2);if (view.Positive()){*this = value;}else{*this = -value;}break;}case base::bit::FloatNumberValueType::Denormalized:{base::Fraction f1 = base::pow(base::BigInteger{2},base::BigInteger{-1022});base::Fraction f2 = base::Fraction{view.MantissaBits(),base::pow(base::BigInteger{2}, base::BigInteger{52}),};base::Fraction value = f1 * f2;if (view.Positive()){*this = value;}else{*this = -value;}break;}case base::bit::FloatNumberValueType::NaN:{throw std::invalid_argument{CODE_POS_STR + "此浮点数是 NaN."};}case base::bit::FloatNumberValueType::PositiveInfinite:{throw std::invalid_argument{CODE_POS_STR + "此浮点数是正无穷。"};}case base::bit::FloatNumberValueType::NegativeInfinite:{throw std::invalid_argument{CODE_POS_STR + "此浮点数是负无穷。"};}default:{throw std::runtime_error{CODE_POS_STR + "非法的枚举值。"};}}
}

无损地将标准库中的 π \pi π 常数转换为分数

#include "base/math/Fraction.h"
#include "base/wrapper/number-wrapper.h"
#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <numbers>
#include <stdlib.h>int main()
{{base::Fraction f{base::Double{std::numbers::pi}};constexpr int precision = 512;std::cout << "分数: " << f << std::endl;std::cout << "std::numbers::pi: \t\t"<< std::setprecision(precision)<< std::numbers::pi<< std::endl;std::cout << "分数表示的 pi 转为 double: \t"<< std::setprecision(precision)<< static_cast<double>(f)<< std::endl;std::cout << "误差: "<< std::setprecision(precision)<< static_cast<double>(f) - std::numbers::pi<< std::endl;}
}

运行结果

分数: 884279719003555 / 281474976710656
std::numbers::pi:               3.141592653589793115997963468544185161590576171875
分数表示的 pi 转为 double:      3.141592653589793115997963468544185161590576171875
误差: 0

在这里插入图片描述

π \pi π 用分数近似表示就是 884279719003555 / 281474976710656

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/84545.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/84545.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端实现截图的几种方法

前端实现截图的几种方法 前端实现截图功能有多种方式&#xff0c;下面我将介绍几种常用的方法及其实现方案。 1. 使用 html2canvas 库 html2canvas 是最流行的前端截图解决方案之一&#xff0c;它可以将 DOM 元素转换为 canvas。 基本用法 import html2canvas from html2c…

TDengine 与开源可视化编程工具 Node-RED 集成

简介 Node-RED 是由 IBM 开发的基于 Node.js 的开源可视化编程工具&#xff0c;通过图形化界面组装连接各种节点&#xff0c;实现物联网设备、API 及在线服务的连接。同时支持多协议、跨平台&#xff0c;社区活跃&#xff0c;适用于智能家居、工业自动化等场景的事件驱动应用开…

OpenCV——图像形态学

图像形态学 一、像素的距离二、像素的邻域三、膨胀与腐蚀3.1、结构元素3.2、腐蚀3.3、膨胀 四、形态学操作4.1、开运算和闭运算4.2、顶帽和黑帽4.3、形态学梯度4.4、击中击不中 一、像素的距离 图像中像素之间的距离有多种度量方式&#xff0c;其中常用的有欧式距离、棋盘距离…

在Django中把Base64字符串保存为ImageField

在数据model中使用ImageField来管理avatar。 class User(models.Model):AVATAR_COLORS ((#212736, Black),(#2161FD, Blue),(#36B37E, Green),(#F5121D, Red),(#FE802F, Orange),(#9254DE, Purple),(#EB2F96, Magenta),)def generate_filename(self, filename):url "av…

使用 R 处理图像

在 R 中进行图像处理&#xff0c;使用像 imager 这样的包&#xff0c;可以实现强大的数字图像分析和处理。本博客将基于"图像数据分析"文档的概念&#xff0c;演示使用 imager 包进行的关键技术——图像增强、去噪和直方图均衡化&#xff0c;并通过可视化结果展示这些…

一命速通Prometheus+Grafana+Consul+VictoriaMetrics

Prometheus业务 搭建及使用 注意&#xff1a;优先看完提供的博客链接&#xff0c;可以快速了解该工具的功能及其搭建和使用。 prometheusgrafana 一、PrometheusGrafana普罗米修斯&#xff0c;搭建和使用_普罗米修斯 grafana-CSDN博客 ./prometheus --config.fileprometheus.ym…

蚂蚁百宝箱快速创建智能体AI小程序

蚂蚁百宝箱官网https://tbox.alipay.com/community?operationSource1006/ 以下是一篇关于蚂蚁百宝箱快速创建智能体 AI 小程序的图文并茂的博客&#xff1a; 标题&#xff1a;蚂蚁百宝箱快速创建智能体 AI 小程序&#xff0c;开启智能应用新体验 引言 在数字化飞速发展的当…

大模型面试题:RL Scaling Law 中的“过优化”现象及其缓解方法是啥?

更多面试题&#xff0c;请看 大模型面试题总结-CSDN博客 或者 https://gitee.com/lilitom/ai_interview_questions/blob/master/README.md 最好将URL复制到浏览器中打开&#xff0c;不然可能无法直接打开 ---------------------------------------------------------------…

Filecoin系列 - IPLD 技术分析

1. 用途 1.1 存储数据 为了成功地将数据加到 Filecoin 网络, 需要成功完成以下步骤: 客户端导入数据生成CAR文件: 数据必须打包成 CAR file (内容可寻址档案) - CAR是IPLD规范的序列化归档文件.存储交易: 存储供应商和客户之间的存储交易必须由客户发起, 并由存储供应商接受…

Apptrace如何帮我精准追踪移动广告效果?

开发者视角&#xff1a;Apptrace如何帮我精准追踪移动广告效果&#xff1f;​​ 作为独立开发者&#xff0c;我最头疼的就是​“广告投放到底有没有用&#xff1f;”​——钱花出去了&#xff0c;用户是刷量机器人还是真实用户&#xff1f;哪个渠道的ROI最高&#xff1f;Apptr…

【MySQL篇07】:redo log日志与buffer pool详解

文章目录 1. Buffer Pool 缓冲池2. redo log (重做日志)redo log 的作用&#xff1a;为什么需要 redo log buffer&#xff1f;什么时候刷盘呢&#xff1f; 3. 总结一下 redo log 和 Buffer Pool 在更新数据时的协同工作关键组件关系图刷盘完成后 1. Buffer Pool 缓冲池 首先&a…

Qt Library库系列----Serial串口

前言 每次写串口相关的功能时&#xff0c;总是需要重新写或者复制原来写过的文件&#xff0c;容易出错不说&#xff0c;这也不是码农的风格&#xff0c;所以还是得有一套自己得代码库&#xff0c;方便调用&#xff0c;又能保持神秘感。 一、开发需求 1.有个实例类&#xff1b;…

第八节:Vben Admin 最新 v5.0 (vben5) 快速入门 - 用户管理(下)

Vben5 系列文章目录 💻 基础篇 ✅ 第一节:Vben Admin 最新 v5.0 (vben5) 快速入门 ✅ 第二节:Vben Admin 最新 v5.0 (vben5) 快速入门 - Python Flask 后端开发详解(附源码) ✅ 第三节:Vben Admin 最新 v5.0 (vben5) 快速入门 - 对接后端登录接口(上) ✅ 第四节:Vben Ad…

Redis 性能瓶颈时如何处理?

当 Redis 遇到性能瓶颈时&#xff0c;需要从多个维度进行排查和优化。以下是系统化的解决方案&#xff0c;涵盖硬件、配置、数据模型、网络等关键点&#xff1a; 一、硬件资源优化 内存瓶颈 现象&#xff1a;频繁触发 OOM 或 used_memory 接近物理内存。解决&#xff1a; 升级服…

多相机三维人脸扫描仪:超写实数字人模型制作“加速器”

超写实数字人&#xff0c;又称“数字分身”&#xff0c;是以真人形象为原型构建的高仿真虚拟形象&#xff0c;按维度可分为2D数字人与3D数字人。这类数字人已广泛应用于影视制作、游戏交互、品牌直播等场景&#xff0c;其核心价值在于通过技术手段实现真人形象的数字化复刻&…

ceph 自动调整 pg_num

要让 Ceph 的 pool 自动调整 pg_num(PG 数量),你需要启用 PG autoscaler。这是从 Ceph Octopus(15.x) 开始引入的功能,能根据池的容量和对象数量自动建议或调整 pg_num,以实现负载均衡。 ✅ 一步步开启 Pool 的 pg_num 自动调整 1. 启用 PG autoscaler 模块(通常默认启…

Python Beautiful Soup 4【HTML/XML解析库】 简介

全面剖析大模型 图解大模型&#xff1a;生成式AI原理与实战 大语言模型大模型应用开发Transformer DeepSeek模型原理开发深度学习 图灵出品 大模型强化学习详解 大模型算法&#xff1a;强化学习、微调与对齐&#xff08;全彩&#xff09;详解强化学习 RLHF GRPO DPO SFT CoT D…

AI Agent开发与安全

AI Agent的核心演进 Level 1&#xff1a;LLM Agent&#xff08;聊天机器人&#xff09; 特点&#xff1a;靠提示词工程赋予人设&#xff08;如星座占卜、角色扮演&#xff09;&#xff0c;但存在幻觉问题&#xff0c;输出不可控。局限&#xff1a;娱乐性强&#xff0c;难胜任严…

NumPy玩转数据科学

本文在创作过程中借助 AI 工具辅助资料整理与内容优化。图片来源网络。 文章目录 一、引言二、NumPy 概述2.1 NumPy 的定义与发展2.2 NumPy 的重要性 三、NumPy 的多维数组支持3.1 多维数组的概念3.2 多维数组的创建与操作3.2.1 数组的创建3.2.2 数组的索引和切片3.2.3 数组的运…

【uniapp小程序开发】图表组件ucharts的使用(入门)

一、插件的安装 安装非常简单&#xff0c;打开uniapp的插件市场&#xff0c;导入到项目中即可 下载地址&#xff1a;https://ext.dcloud.net.cn/plugin?id271 二、开始实践 先看页面的效果 页面中实现了三个基本图形的展示&#xff1a;折线图、饼图和柱状图。 上图左一&a…