正弦函数解析(sin.rs)

news2025/1/4 10:09:26

sin.rs文件提供了sin函数的实现,它计算并返回一个浮点数(f64类型)的正弦值。这个函数首先处理了一些特殊情况,如极小的值、无穷大和NaN(非数字),然后使用rem_pio2函数将输入参数x归约到[-π/2, π/2]的范围内,并根据归约的结果和n的值(n是x除以π/2的商的整数部分,对4取模的结果),选择调用k_sin或k_cos函数来计算最终的正弦值。

一、代码中关键部分的解释

1. 特殊值处理

  • 如果x的绝对值非常小(小于2^-26),函数会直接返回x,因为在这个范围内,sin(x)的值非常接近x。
  • 如果x是无穷大或NaN,函数会返回NaN。

2. 参数归约

使用rem_pio2函数将x归约到[-π/2, π/2]范围内,并返回三个值:n(x除以π/2的商的整数部分),y0(x的归约值的主要部分),和y1(x的归约值的次要部分,用于提高精度)。

3. 选择正确的函数来计算正弦值

根据n的值(对4取模),选择调用k_sin或k_cos函数,并可能取反。这是因为正弦和余弦函数在[-π/2, π/2]范围内是对称的,并且可以通过旋转坐标系来相互转换。

4. 测试

提供了一个测试函数test_near_pi,它测试了当x接近π时的正弦值计算是否正确。注意,由于浮点数的表示误差,测试值可能不是精确的π,而是一个接近π的浮点数。

5. force_eval!宏:

这个宏在代码中用于确保某些表达式被评估,即使编译器可能认为它们对最终结果没有影响。如浮点数的精度限制、下溢等。这在处理极小值或强制触发浮点异常时特别有用。但是它是不安全的,会因为特定硬件产生错误,不建议使用。代码如下:

macro_rules! force_eval {
    ($e:expr) => {
        unsafe { ::core::ptr::read_volatile(&$e) }
    };
}

6. 位操作和浮点表示:

代码使用了位操作来提取浮点数的指数和尾数部分,以及通过特定的位模式来构造特定的浮点数(如x1p120,它表示2^120)。
请注意,k_sin和k_cos函数以及rem_pio2函数的具体实现在这段代码中没有给出。这些函数是计算正弦和余弦值的核心,rem_pio2函数负责将输入参数归约到基本区间内。
此外,#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]属性是一个条件编译属性,它在启用了测试和assert_no_panic特性时,确保sin函数不会引发恐慌(panic)。这对于编写健壮的库函数非常重要,因为它们不应该在正常情况下崩溃。

二、源代码

use super::{k_cos, k_sin, rem_pio2};

// sin(x)
// 返回x的正弦函数。
//
// 核心函数:
//      k_sin            ... [-pi/4,pi/4]上的正弦函数
//      k_cos            ... [-pi/4,pi/4]上的余弦函数
//      rem_pio2         ... argument reduction routine
//
// 方法。
//设S、C分别表示[-PI/4、+PI/4]上的sin、cos。在[-pi/4,+pi/4]中,将参数x减小到y1+y2=x-k*pi/2,并设n=k mod 4。
//我们有
//
//          n        sin(x)      cos(x)
//     --------------------------------
//          0          S           C   
//          1          C          -S   
//          2         -S          -C   
//          3         -C           S   
//     --------------------------------
//
//特殊情况:
//设trig为“sin”或“cos”中的任何一个。
//trig(+-INF)是NaN,带有信号;
//trig(NaN)是NaN;

//准确度:
//TRIG(x)返回几乎四舍五入的TRIG(x)

/// x的正弦(f64)。(sine)
///
/// x单位是弧度。
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
pub fn sin(x: f64) -> f64 {
    let x1p120 = f64::from_bits(0x4770000000000000); // x1p120 == 2^120

    /* High word of x. */
    let ix = (f64::to_bits(x) >> 32) as u32 & 0x7fffffff;//去除符号位,即提取指数11位和尾数前20位

    /* |x| ~< pi/4 */
    if ix <= 0x3fe921fb {//等同于不超过后32位都是1的值(即0.7853984832763671),pi/4的值为0.785398163397448309615660845819875721_f64,会有略大于pi/4的数放进来。
        if ix < 0x3e500000 {// 2^-26,即1.4901161193847656e-8,考虑后32位可能都是1,即1.4901175404702368e-8
            /* |x| < 2**-26 */
            /* 如果x!=0,则提高不精确性0,如果低于正常值,则下溢*/
            if ix < 0x00100000 {//即非约数或0,
                force_eval!(x / x1p120);//制造一个下溢
            } else {
                force_eval!(x + x1p120);//小数加大数,结果小数被舍去,是否有报错信息就不清楚了
            }
            return x;//以上程序说明,|x|足够小时,即小于1.4901175404702368e-8时返回 x
        }
        return k_sin(x, 0.0, 0);//-45°至45°排除小值后调用该函数。
    }

    /* sin(无穷大 或 非数时返回非数 */
    if ix >= 0x7ff00000 {
        return x - x;//返回NaN值
    }

    /* 将输入参数归约到一个周期内的值来简化计算 */
    let (n, y0, y1) = rem_pio2(x);//调用归约函数
    match n & 3 {
        0 => k_sin(y0, y1, 1),
        1 => k_cos(y0, y1),
        2 => -k_sin(y0, y1, 1),
        _ => -k_cos(y0, y1),
    }
}

#[test]
fn test_near_pi() {
    let x = f64::from_bits(0x400921fb000FD5DD); // 3.141592026217707
    let sx = f64::from_bits(0x3ea50d15ced1a4a2); // 6.273720864039205e-7
    let result = sin(x);
    #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
    let result = force_eval!(result);
    assert_eq!(result, sx);
}

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

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

相关文章

前端超大缓存IndexDB、入门及实际使用

文章目录 往期回顾项目实战初始化表获取列表新增表的数据项获取详情根据ID获取详情根据其他字段获取详情 删除数据 总结 往期回顾 在之前的文章中&#xff0c;我们介绍了IndexDB vs Cookies vs Session这几个的对比&#xff0c;但是没有做实际项目的演示&#xff0c;今天我们用…

面试题解,JVM的运行时数据区

一、请简述JVM运行时数据区的组成结构及各部分作用 总览 从线程持有的权限来看 线程私有区 虚拟机栈 虚拟机栈是一个栈结构&#xff0c;由许多个栈帧组成&#xff0c;一个方法分配一个栈帧&#xff0c;线程每执行一个方法时都会有一个栈帧入栈&#xff0c;方法执行结束后栈帧…

WAV文件双轨PCM格式详细说明及C语言解析示例

WAV文件双轨PCM格式详细说明及C语言解析示例 一、WAV文件双轨PCM格式详细说明1. WAV文件基本结构2. PCM编码方式3. 双轨PCM格式详细说明二、C语言解析WAV文件的代码示例代码说明一、WAV文件双轨PCM格式详细说明 WAV文件是一种用于存储未压缩音频数据的文件格式,广泛应用于音频…

QT------模型/视图

一、模型/视图结构概述 基本原理&#xff1a; Qt 的模型/视图&#xff08;Model/View&#xff09;架构将数据的存储和显示分离&#xff0c;提高了代码的可维护性和复用性。模型&#xff08;Model&#xff09;&#xff1a;负责存储和管理数据&#xff0c;提供数据的访问接口&am…

vue3+ts+element-plus 表单el-form取消回车默认提交

问题描述&#xff1a;在表单el-form中的el-input中按回车后&#xff0c;页面会刷新&#xff0c;url也会改变&#xff0c; 回车前&#xff1a; 回车后&#xff1a; 相关代码&#xff1a; 解决方法1&#xff1a;在 el-form 上阻止默认的 submit 事件&#xff0c;增加 submit.pre…

掌握大数据处理利器:Flink 知识点全面总结【上】

1.Flink的特点 Apache Flink 是一个框架和分布式处理引擎&#xff0c;用于对无界和有界数据流进行状态计算。 Flink主要特点如下&#xff1a; 高吞吐和低延迟。每秒处理数百万个事件&#xff0c;毫秒级延迟。结果的准确性。Flink提供了事件时间(event--time)和处理时间(proces…

国产数据库-崖山使用介绍

本文档基于崖山数据库23.3 个人版本&#xff0c;单机&#xff08;主备&#xff09;部署模式的情况下的使用介绍。 数据库实例状态&#xff1a; NOMOUNT&#xff1a;仅读取参数文件&#xff0c;不加载数据库 MOUNT&#xff1a;读取控制文件&#xff0c;加载数据库&#xff…

Pytest基础01: 入门demo脚本

目录 1 Pytest接口测试 1.1 最简单版hello world 1.2 pytest.ini 2 pytest兼容unittest 3 封装pytest执行入口 1 Pytest接口测试 Pyest是一个可以用于接口测试的强大框架&#xff0c;开源社区也有非常多的pytest插件。 按江湖传统&#xff0c;学习一个新语言或者新框架&…

如何在没有 iCloud 的情况下将数据从 iPhone 传输到 iPhone

概括 您可能会遇到将数据从 iPhone 转移到 iPhone 的情况&#xff0c;尤其是当您获得新的 iPhone 15/14 时&#xff0c;您会很兴奋并希望将数据转移到它。 使用iCloud最终可以做到这一点&#xff0c;但它的缺点也不容忽视&#xff0c;阻碍了你选择它。例如&#xff0c;您需要…

streamlit、shiny、gradio、fastapi四个web APP平台体验

streamlit、shiny、gradio、fastapi四个web APP平台体验 经常被问的问题就是&#xff1a;web APP平台哪个好&#xff1f;该用哪个&#xff1f;刚开始只有用streamlit和shiny&#xff0c;最近体验了一下gradio和fastapi&#xff0c;今天根据自己的体会尝试着回答一下。 使用R语…

HTML5滑块(Slider)

HTML5 的滑块&#xff08;Slider&#xff09;控件允许用户通过拖动滑块来选择数值。以下是如何实现一个简单的滑块组件的详细说明。 HTML5 滑块组件 1. 基本结构 使用 <input type"range"> 元素可以创建一个滑块。下面是基本实现的代码示例&#xff1a; <…

探索 .idea 文件夹:Java Maven 工程的隐形守护者

一、.idea文件夹深度解析&#xff1a;IntelliJ IDEA项目配置的核心 在Java Maven工程的开发环境中&#xff0c;.idea文件夹扮演着举足轻重的角色。这是IntelliJ IDEA项目特有的一个配置文件夹&#xff0c;它包含了项目所需的各种配置信息&#xff0c;以确保项目能够在不同的开发…

遥感图像车辆检测-目标检测数据集

遥感图像车辆检测-目标检测数据集&#xff08;包括VOC格式、YOLO格式&#xff09; 数据集&#xff1a; 链接: https://pan.baidu.com/s/1XVlRTVWpXZFi6ZL_Xcs7Rg?pwdaa6g 提取码: aa6g 数据集信息介绍&#xff1a; 共有 1035 张图像和一一对应的标注文件 标注文件格式提供了…

[Qt] Qt介绍 | 搭建SDK

目录 1. Qt 简介 什么是 Qt&#xff1f; 1.1 引入 1.2 GUI 1.3 Qt 介绍 2. Qt 发展史 3. Qt 支持的平台 4. Qt 版本信息 5. Qt 的优点 6. Qt 应用场景 7. Qt 成功案例 8. Qt 发展前景及就业分析 二. Qt 开发环境搭建 1. 开发工具概述 2.Qt SDK 安装 3.使用 1. …

【机器学习】机器学习的基本分类-自监督学习-对比学习(Contrastive Learning)

对比学习是一种自监督学习方法&#xff0c;其目标是学习数据的表征&#xff08;representation&#xff09;&#xff0c;使得在表征空间中&#xff0c;相似的样本距离更近&#xff0c;不相似的样本距离更远。通过设计对比损失函数&#xff08;Contrastive Loss&#xff09;&…

xterm + vue3 + websocket 终端界面

xterm.js 下载插件 // xterm npm install --save xterm// xterm-addon-fit 使终端适应包含元素 npm install --save xterm-addon-fit// xterm-addon-attach 通过websocket附加到运行中的服务器进程 npm install --save xterm-addon-attach <template><div :…

记一次护网通过外网弱口令一路到内网

视频教程在我主页简介或专栏里 目录&#xff1a; 资产收集 前期打点 突破 完结 又是年底护网季&#xff0c;地市护网有玄机&#xff0c;一路磕磕又绊绊&#xff0c;终是不负领导盼。 扯远了-_-!!&#xff0c;年底来了一个地市级护网&#xff0c;开头挺顺利的&#xff0c…

XIAO ESP32 S3网络摄像头——2视频获取

本文主要是使用XIAO Esp32 S3制作网络摄像头的第2步,获取摄像头图像。 1、效果如下: 2、所需硬件 3、代码实现 3.1硬件代码: #include "WiFi.h" #include "WiFiClient.h" #include "esp_camera.h" #include "camera_pins.h"// 设…

uniapp:微信小程序文本长按无法出现复制菜单

一、问题描述 在集成腾讯TUI后&#xff0c;为了能让聊天文本可以复制&#xff0c;对消息组件的样式进行修改&#xff0c;主要是移除下面的user-select属性限制&#xff1a; user-select: none;-webkit-user-select: none;-khtml-user-select: none;-moz-user-select: none;-ms…

2025:OpenAI的“七十二变”?

朋友们&#xff0c;准备好迎接AI的狂欢了吗&#xff1f;&#x1f680; 是不是跟我一样&#xff0c;每天醒来的第一件事就是看看AI领域又有什么新动向&#xff1f; 尤其是那个名字如雷贯耳的 OpenAI&#xff0c;简直就是AI界的弄潮儿&#xff0c;一举一动都牵动着我们这些“AI发…