在 C 中生成正弦信号而不使用标准函数

2024-01-04

我想在 C 语言中生成正弦信号,而不使用标准函数 sin() 来触发 LED 亮度的正弦形变化。我的基本想法是使用具有 40 个点和插值的查找表。

这是我的第一个方法:

const int sine_table[40] = {0, 5125, 10125, 14876, 19260, 23170, 26509, 29196,
31163, 32364, 32767,  32364, 31163, 29196, 26509, 23170, 19260, 14876, 10125,
5125, 0, -5126, -10126,-14877, -19261, -23171, -26510, -29197, -31164, -32365,
-32768, -32365, -31164, -29197, -26510, -23171, -19261, -14877, -10126, -5126};

int i = 0;
int x1 = 0;
int x2 = 0;
float y = 0;

float sin1(float phase)
{
    x1 = (int) phase % 41;
    x2 = x1 + 1;
    y = (sine_table[x2] - sine_table[x1])*((float) ((int) (40*0.001*i*100) % 4100)/100 - x1) + sine_table[x1];
    return y;
}

int main()
{
    while(1)
    {
    printf("%f      ", sin1(40*0.001*i)/32768);
    i = i + 1;
    }
}

不幸的是,这个函数有时返回远大于 1 的值。此外,插值似乎不太好(我用它来创建 LED 的正弦形状亮度变化,但这些非常不平滑)。

有人有更好的主意用 C 语言实现正弦发生器吗?


OP 的主要问题是生成表查找的索引。

OP的代码尝试访问外部数组sine_table[40]导致未定义的行为 https://en.wikipedia.org/wiki/Undefined_behavior。至少解决这个问题。

const int sine_table[40] = {0, 5125, 10125, ...
    ...
    x1 = (int) phase % 41;                     // -40 <= x1 <= 40
    x2 = x1 + 1;                               // -39 <= x2 <= 41  
    y = (sine_table[x2] - sine_table[x1])*...  // bad code, consider x1 = 40 or x2 = 40,41

建议更改

    x1 = (int) phase % 40;   // mod 40, not 41
    if (x1 < 0) x1 += 40;    // Handle negative values
    x2 = (x1 + 1) % 40;      // Handle wrap-around 
    y = (sine_table[x2] - sine_table[x1])*...  

存在更好的方法,但重点关注 OP 的方法,请参见下文。

#include <math.h>
#include <stdio.h>

const int sine_table[40] = { 0, 5125, 10125, 14876, 19260, 23170, 26509, 29196,
31163, 32364, 32767, 32364, 31163, 29196, 26509, 23170, 19260, 14876, 10125,
5125, 0, -5126, -10126, -14877, -19261, -23171, -26510, -29197, -31164, -32365,
-32768, -32365, -31164, -29197, -26510, -23171, -19261, -14877, -10126, -5126 };

int i = 0;
int x1 = 0;
int x2 = 0;
float y = 0;

float sin1(float phase) {
  x1 = (int) phase % 40;
  if (x1 < 0) x1 += 40;
  x2 = (x1 + 1) % 40;
  y = (sine_table[x2] - sine_table[x1])
      * ((float) ((int) (40 * 0.001 * i * 100) % 4100) / 100 - x1)
      + sine_table[x1];
  return y;
}

int main(void) {
  double pi = 3.1415926535897932384626433832795;
  for (int j = 0; j < 1000; j++) {
    float x = 40 * 0.001 * i;
    float radians = x * 2 * pi / 40;
    printf("%f %f %f\n", x, sin1(x) / 32768, sin(radians));
    i = i + 1;
  }
}

Output

         OP's     Reference sin()
0.000000 0.000000 0.000000
0.040000 0.006256 0.006283
0.080000 0.012512 0.012566
...
1.960000 0.301361 0.303035
2.000000 0.308990 0.309017
2.040000 0.314790 0.314987
...
39.880001 -0.020336 -0.018848
39.919998 -0.014079 -0.012567
39.959999 -0.006257 -0.006283

更好的代码不会传递值i, x1, x2, y作为全局变量,但作为函数参数或函数变量。也许这是OP调试的产物。


有人有更好的主意用 C 语言实现正弦发生器吗?

这是相当广泛的。在速度、精度、代码空间、可移植性或可维护性方面更好?sine()功能很容易制作。高品质的东西需要更多的努力。

尽管模糊,OP 使用小型查找表是一个好的开始 - 尽管我认为它可以在没有任何浮点数学的情况下完成。我建议 OP 构建一个经过测试和工作的解决方案并将其发布在代码审查 https://codereview.stackexchange.com寻求改进想法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 C 中生成正弦信号而不使用标准函数 的相关文章

  • 为什么我的 C#/pinvoke DeviceIoControl 调用返回 0 字节读取的垃圾数据?

    我有一个运行良好的非托管 C Windows 控制台应用程序 我想要它在 C 中 我已经为必要的 Kernel32 dll 符号完成了 DllImport 语句 StructLayout LayoutKind Sequential inte
  • 在列表中查找匹配项的最简洁方法

    在列表中查找内容的最佳方式是什么 我知道 LINQ 有一些不错的技巧 但我们也可以获取有关 C 2 0 的建议 让我们对这个常见的代码模式进行最佳重构 目前我使用这样的代码 mObjList is a List
  • 将列表数组中的值绑定到列表框

    任何机构都可以给出一个简短的示例 用于将列表数组中的值绑定到 c net 中的列表框 这取决于您的列表数组的情况 让我们从一个简单的示例开始 List
  • 无法在表适配器配置属性中找到对象“Web.config”的连接“MyConnName”

    I want to change the query in table adapter but it s not opening throwing an error Configure table Adapter Failed in pro
  • Visual Studio 2015 C# 找不到参考

    我在使用 Visual Studio 2015 和 C 时遇到了问题 在同一解决方案中添加对其他项目的引用时 Visual Studio 找不到所有类 例如 我创建了一个单元测试项目 我添加了对我创建的通信项目的引用 库中有 10 个类 但
  • MSVC10 /MP 在项目中跨文件夹构建非多核

    我希望有人指出我们所遇到的错误或解决方法 使用 MP 编译项目时 似乎仅同时编译同一文件夹中的文件 我使用进程资源管理器来滑动命令行并确认行为 项目过滤器似乎对同时编译的内容没有影响 项目结构disk Folder project vcxp
  • 我可以将特定警告视为错误吗?

    以下是我有时在学生代码中看到的模式的简化版本 bool foobar int a int b if a lt b return true 当然 真正的代码要复杂得多 Visual Studio 报告警告 C4715 并非所有控制路径都会返回
  • 使用 Process.Start() 打开文件夹时访问被拒绝异常

    我有一个 C 中的 winforms 应用程序 我必须在其中打开某个文件夹 我用 System Diagnostics Process Start pathToFolder 这会导致以下异常 System ComponentModel Wi
  • memccpy 返回比 src 起始地址更低的内存地址

    我有一个学校项目 我必须重新编码memccpy 功能 我使用 2 个程序来检查我的代码是否正常工作 第一个是只有一个主程序的小程序 第二个程序是另一个学生开发的 可以找到here https github com yyang42 mouli
  • 在 OpenGL 中使用不同的着色器程序?

    我必须在 OpenGL 中针对不同的对象使用两个不同的着色器程序 我发现我必须使用glUseProgram 在不同的着色器程序之间切换 但对此没有太多信息 鉴于我有两个用于不同对象的不同着色器程序 如何为每个着色器程序生成和绑定 VAO 和
  • 如何将对 System.Data.DataSetExtensions 的引用添加到网站 ascx.cs 文件?

    我们正在处理一个网站项目并尝试参考System Data DataSetExtensions 使用 Web 应用程序会更好 不过 技术主管有她的理由 这是我们尝试过的 找到装配路径 打开 Visual Studio 命令提示符并运行sn e
  • 如何在Phone类库项目中添加ResourceDictionary并访问它

    我正在开发一个项目 其中我有一个引用图书馆项目的子项目 在我的库项目 电话类库 中 如何创建 ResourceDictionary xaml 其中我需要添加一些样式并在 xaml 文件和 cs 文件中使用它 我需要访问 xaml 文件中的
  • 验证域用户凭据

    我需要一种方法来验证 Windows 上本机 C 的用户 密码对 输入的是用户名和密码 用户可以是 DOMAIN user 格式 基本上我需要编写一个函数 如果用户 密码是有效的本地帐户 则返回 true 第1部分 如果用户 密码在给定的域
  • 如何从 Function App 设置会话 ID 或创建自定义字段到 Application Insights

    功能应用程序如下 public static async Task
  • PARITY_NONE 是 C++ Windows 中的关键字吗?

    我正在使用 boost 编写一个串行库 并且我有一个枚举 enum parity t PARITY NONE PARITY ODD PARITY EVEN 我收到如下错误 错误 1 错误 C2059 语法错误 我无法弄清楚问题是什么 然后我
  • C 中函数“fgets”的参数太少

    每当我编译这个错误时 我都会收到该错误 但我不知道为什么 我直接从书上抄袭这个 有人可以帮忙吗 include
  • 不兼容的指针到字符转换

    我正在编写一个程序 将卡片值写入 52 个点字符的多维数组中 该程序是一个测试数组 稍后我将其作为函数写入主程序中 在程序中 我通过以下方式初始化 for 循环计数0通过51 我用一个switch语句调制13将卡牌值分配给数组点 但是 我收
  • 如何在您的网站中连接两个人

    有一款名为 Verbosity 的游戏 这是一款有目的的游戏 位于此链接上www gwap com 在游戏中 他们随机连接两个玩家互相玩 游戏是玩家1应该向他的搭档 玩家2 描述一个单词 而玩家2应该猜测这个单词 我正在尝试建立一个网站来执
  • 频繁插入已排序的集合

    我已经对集合 列表 进行了排序 并且我需要始终保持其排序 我目前在我的集合上使用 List BinarySearch 然后在正确的位置插入元素 我也尝试过在每次插入后对列表进行排序 但性能不可接受 有没有一种解决方案可以提供更好的性能 也许
  • ASP.NET API:尚未为此 DbContext 配置数据库提供程序

    我正在尝试从我的 Net Core API 项目连接到 MySql 数据库 这是我的上下文类 public class MyContext DbContext public MyContext public MyContext DbCont

随机推荐

  • 如何将长日期值转换为 mm/dd/yyyy 格式[重复]

    这个问题在这里已经有答案了 可能的重复 将长字符串转换为日期 https stackoverflow com questions 11753341 converting long string to date 我需要转换long日期值至月
  • 如何对应用程序状态建模?

    我正在编写一个游戏 我想以一种干净的 面向对象的方式对其不同的状态进行建模 我猜 Game Maker 的类比是框架 以前 我是通过以下方式完成的 class Game enum AppStates APP STARTING APP TIT
  • SQL Server 数据库迁移向导发生了什么?

    SQL Server 数据库迁移向导 又名 SQL Azure 迁移向导 以前位于http sqlazuremw codeplex com http sqlazuremw codeplex com 但已经消失了 我试图通过谷歌搜索它的新家
  • 未找到带标签的句柄可放入图例折线图中

    我正在使用 matplotlib 绘制折线图 在所有其他情况下 它通常会自动检测图例 但这次我使用数据透视表来绘制图表 我认为这会阻止它 我不确定如何绘制图例 No handles with labels found to put in l
  • GWT + 流程构建器

    是否可以将 ProcessBuilder 与 GWT 一起使用 当我声明一个新 ProcessBuilder 的实例时 我得到 java lang ProcessBuilder is not supported by Google App
  • 将 .Glade(或 xml)文件转换为 C 源代码的工具

    我正在寻找可以将 Glade 或 xml 文件转换为 C 源代码的工具 我尝试过 g2c Glade To C Translator 但我正在寻找 Windows 二进制文件 任何人都知道有什么好的窗口工具 Thanks PP 你不需要工具
  • Firebase 存储下载我上传的原始文本,而不仅仅是网址

    我上传了一个原始的String使用提供的示例对 firebase 存储进行 测试 here https firebase google com docs storage web upload files upload from a stri
  • DatePicker 的 setMinDate() [重复]

    这个问题在这里已经有答案了 我在几个地方看到了有关堆栈溢出的这个问题 但给出的答案对我不起作用 所以我在这里 我需要将日期选择器的最小日期动态设置为当前日期 我的最低 API 是 12 我试过这个 Calendar minCalendar
  • 如何阻止一个节点上的死锁导致整个集群崩溃?

    我正在 MariaDB 下运行 3x 节点 Galera 集群 该应用程序采用 PHP 语言 使用 mysqli 扩展 偶尔我会得到一个Deadlock https dev mysql com doc refman 5 5 en error
  • 使用 javascript 更改图像不透明度

    如何使用 javascript 更改图像不透明度 我将使用 javascript 创建淡入淡出效果 有示例吗 有没有像 image opacity 这样的东西可以通过 JS 代码更改 它是如何设置的 thanks 假设您使用纯 JS 请参阅
  • Spring @Autowire 关于属性与构造函数

    因此 由于我一直在使用 Spring 如果我要编写一个具有依赖项的服务 我将执行以下操作 Component public class SomeService Autowired private SomeOtherService someO
  • 如何获取网页的最后修改日期? [复制]

    这个问题在这里已经有答案了 我想知道如何使用 C 获取网页的最后修改日期 我尝试了下面的代码 但我只得到今天的日期 HttpWebRequest req HttpWebRequest WebRequest Create http www c
  • React 开发工具中组件的forwardRef 是什么意思以及如何使用它?

    当我在 React 开发工具中检查组件结构时 我可以看到有一个forwardRef标记 我很困惑 因为源代码中没有使用它的迹象 它是怎么存在的以及我该如何使用它 The forwardRef调用不在您自己的代码中 它们在您正在使用的包中 s
  • 输入毫无意义的签名

    Consider a gt a gt a gt Bool 这个签名有什么有意义的定义吗 也就是说 定义不是简单地忽略论证 x gt a gt Bool 看来这样的签名还有很多 可以立即排除 Carsten K nig 在评论中建议使用自由定
  • 如何在 grep 中使用 POSIXLY_CORRECT?

    有一个变量POSIXLY CORRECT https www gnu org software bash manual bashref html index POSIXLY 005fCORRECT in Bash POSIXLY CORRE
  • TFS 2017:在同一 TFS 服务器上克隆/复制集合

    我想在同一个 TFS 服务器上创建我们的生产集合的克隆 副本 以用作沙箱 开发环境 恢复集合的备份并重命名它很容易 但我知道当我尝试附加集合时会出现 GUID 冲突 可能还有其他冲突 有没有办法解决 或者我只需要购买一台带有单独 TFS 实
  • 对齐 OCR 文本

    我正在根据历史记录创建一个数据库 这些历史记录是我从书籍中拍摄的页面 100K 页 在对每个页面进行 OCR 之前 我编写了一些 python 代码来进行一些图像处理 由于这些书中的数据没有采用格式良好的表格 因此我需要将每个页面分为行和列
  • 在java中使用外部硬件组件?

    我谈论的是可以通过某些端口或其他方式从外部连接到计算机系统的组件 而不是属于计算机本身的一部分或外围设备的任何组件 实际上 正在从事一个大学项目 用于控制铁路道口的交通灯和围栏 我有 Java 知识 但我不知道如何让交通灯和吊杆栏杆在基于
  • Swagger-PHP 用于为 Swagger-UI 生成 JSON 文件

    我正在尝试使用 Swagger PHP 生成 JSON 文件 以便我可以将它与 Swagger UI 一起使用来自动记录文档 我尝试了链接 https github com zircote swagger php https github
  • 在 C 中生成正弦信号而不使用标准函数

    我想在 C 语言中生成正弦信号 而不使用标准函数 sin 来触发 LED 亮度的正弦形变化 我的基本想法是使用具有 40 个点和插值的查找表 这是我的第一个方法 const int sine table 40 0 5125 10125 14