我正在try 用C语言实现CORDIC,我必须生成算法使用的常量值.第一个ArcTanGent值列表很简单,但我在第二个列表'Kvalues.'中遇到了麻烦

% Kvalues = cumprod(1./sqrt(1 + 1j*2.^(-(0:23))))
Kvalues = [ ...
   0.70710678118655   0.63245553203368   0.61357199107790   0.60883391251775 ...
   0.60764825625617   0.60735177014130   0.60727764409353   0.60725911229889 ...
   0.60725447933256   0.60725332108988   0.60725303152913   0.60725295913894 ...
   0.60725294104140   0.60725293651701   0.60725293538591   0.60725293510314 ...
   0.60725293503245   0.60725293501477   0.60725293501035   0.60725293500925 ...
   0.60725293500897   0.60725293500890   0.60725293500889   0.60725293500888 ];

然而,我不是很熟悉这个符号,我很难理解它,并产生一个简单的公式,可以产生同样的结果.我不想只是将这些值粘贴到我的CORDIC实现中,因为我希望自己以适当的精确度生成它们.

以下是我根据我的理解得出的结论,但这并不能产生正确的结果:

float prev = 1;
for (int i = 0; i < PRECISION; i++)
    printf("%f\n", prev = prev/sqrt(1+pow(2, -i)));

我期待的价值观和我在维基百科的榜单上看到的一样:

0.707106
0.632455
0.613571
0.608833
0.607648
0.607351

但在我的公式中,它们收敛到0.457942...,而不是0.607252...:

0.707107
0.577350
0.516398
0.486864
0.472328
0.465116

要为CORDIC生成PRECISION 'Kvalues',C中的正确公式是什么?

推荐答案

我在CORDIC上进行了网络搜索,并查看了不同的页面,try 了许多变体[没有显示出来].

从这里:https://nonagon.org/ExLibris/cordic-c-javascript我得到了公式:

prev = prev / sqrt(1 + (1.0 / pow(2, 2.0 * i)))

归根结底,对于您的代码来说,它是更改:

pow(2, -i)

进入:

pow(2, -2.0 * i)

以下是修改后的有效代码:

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

#define PRECISION   6

#define CALL(_fnc) \
    do { \
        printf("\n" #_fnc "\n"); \
        _fnc(); \
    } while (0)

void
orig(void)
{
    double prev = 1.0;

    for (int i = 0; i < PRECISION; i++)
        printf("%f\n", prev = prev / sqrt(1 + pow(2, -i)));
}

void
fix1(void)
{
    float prev = 1;

    for (int i = 0; i < PRECISION; i++)
        printf("%f\n",prev = prev / sqrt(1 + pow(2, -2.0 * i)));
}

int
main(void)
{

    CALL(orig);
    CALL(fix1);

    return 0;
}

以下是程序输出:


orig
0.707107
0.577350
0.516398
0.486864
0.472328
0.465116

fix1
0.707107
0.632456
0.613572
0.608834
0.607648
0.607352

我建议使用double而不是float,并提高printf格式的精度(例如%.14f):

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

#define PRECISION   6

#define CALL(_fnc) \
    do { \
        printf("\n" #_fnc "\n"); \
        _fnc(); \
    } while (0)

void
orig(void)
{
    double prev = 1.0;

    for (int i = 0; i < PRECISION; i++)
        printf("%.14f\n", prev = prev / sqrt(1 + pow(2, -i)));
}

void
fix1(void)
{
    double prev = 1;

    for (int i = 0; i < PRECISION; i++)
        printf("%.14f\n",prev = prev / sqrt(1 + pow(2, -2.0 * i)));
}

int
main(void)
{

    CALL(orig);
    CALL(fix1);

    return 0;
}

以下是增强后的输出:


orig
0.70710678118655
0.57735026918963
0.51639777949432
0.48686449556015
0.47232793895472
0.46511640189705

fix1
0.70710678118655
0.63245553203368
0.61357199107790
0.60883391251775
0.60764825625617
0.60735177014130

C++相关问答推荐

当我try 计算一个多项时,看到segfault.我做错了什么?

使用sd-设备列举设备导致seg错误

librsvg rsvg_handle_get_dimensions获取像素大小与浏览器中的渲染大小没有不同

segfault在C中使用getline()函数

如何在C宏中确定Windows主目录?

C语言中的strstr问题

带有sigLongjMP中断I/O的异常处理程序

在CLANG中调试预处理器宏

这个计算C中阶乘的函数正确吗?

不同出处的指针可以相等吗?

在进程之间重定向输出和输入流的问题

合并对 struct 数组进行排序

错误:字符串在C中获得意外输出

使用正则表达式获取字符串中标记的开始和结束

STM32 FATFS用户手册(Um1721)中的代码正确吗?

如何在MSVC中使用intSafe.h函数?

为什么这个代码的最后一次迭代不能正常工作?

如何在C中计算包含递增和递减运算符的逻辑表达式?

GnuCobol 使用 double 类型的参数调用 C 函数

为什么 int32_t 和 int16_t 在 printf 输出中具有相同的位数?