如何高效地从(CoolFlux BSP32 累加器)小数部分的前 29 位计算十进制值?

问题描述 投票:0回答:0

我正在尝试编写一个C(使用CoolFlux BSP32)程序,该程序将累加器作为输入并显示其十进制值。例如,对于值为十六进制 FF C000 0000 的 acc,我想打印“-1.5”。

小数部分的计算需要误差小于10^(-9),所以我需要使用累加器小数部分的30位。

我尝试使用等于 10 ^ 9 / 2 ^ current_index 的数字序列来重建小数部分,如果 1 / 2 ^ current_index 可以用 30 位表示,并且 (10 ^ 9 / 2 ^ (current_index - 1) ) - 1) / 2 如果 1 / 2 ^ 索引不能用 30 位表示。

代码重现:

#include"cf6_chess.h"
#include"CoolFlux_defs.h"
#include<stdio.h>

void printf_acc(acc x)
{
    fix h;
    h = extract_high(x << 1);
    int32 fractionalPart; // Its value is integer (rather than rational but not integer).
    fractionalPart = 0;
    if(h < 0) //Its MSB is 1?
    {
        fractionalPart = 500000000;
    }
    h <<= 1;
    if(h < 0)
    {
        fractionalPart += 250000000;
    }
    h <<= 1;
    if(h < 0)
    {
        fractionalPart += 125000000;
    }
    h <<= 1;
    if(h < 0)
    {
        fractionalPart += 62500000;
    }
    h <<= 1;
    if(h < 0)
    {
        fractionalPart += 31250000;
    }
    h <<= 1;
    if(h < 0)
    {
        fractionalPart += 15625000;
    }
    h <<= 1;
    if(h < 0)
    {
        fractionalPart += 7812500;
    }
    h <<= 1;
    if(h < 0)
    {
        fractionalPart += 3906250;
    }
    h <<= 1;
    if(h < 0)
    {
        fractionalPart += 1953125;
    }
    h <<= 1;
    if(h < 0)
    {
        fractionalPart += 976562;
    }
    h <<= 1;
    if(h < 0)
    {
        fractionalPart += 488281;
    }
    h <<= 1;
    if(h < 0)
    {
        fractionalPart += 244140;
    }
    h <<= 1;
    if(h < 0)
    {
        fractionalPart += 122070;
    }
    h <<= 1;
    if(h < 0)
    {
        fractionalPart += 61035;
    }
    h <<= 1;
    if(h < 0)
    {
        fractionalPart += 30517;
    }
    h <<= 1;
    if(h < 0)
    {
        fractionalPart += 15258;
    fix low;
    low = extract_low(x << 1);
    if(low < 1)
    {
        fractionalPart += 7629;
    }
    low <<= 1;
    if(low < 1)
    {
        fractionalPart += 3814;
    }
    low <<= 1;
    if(low < 1)
    {
        fractionalPart += 1907;
    }
    low <<= 1;
    if(low < 1)
    {
        fractionalPart += 953;
    }
    low <<= 1;
    if(low < 1)
    {
        fractionalPart += 476;
    }
    low <<= 1;
    if(low < 1)
    {
        fractionalPart += 238;
    }
    low <<= 1;
    if(low < 1)
    {
        fractionalPart += 119;
    }
    low <<= 1;
    if(low < 1)
    {
        fractionalPart += 59;
    }
    low <<= 1;
    if(low < 1)
    {
        fractionalPart += 29;
    }
    low <<= 1;
    if(low < 1)
    {
        fractionalPart += 14;
    }
    low <<= 1;
    if(low < 1)
    {
        fractionalPart += 7;
    }
    low <<= 1;
    if(low < 1)
    {
        fractionalPart += 3;
    }
    low <<= 1;
    if(low < 1)
    {
        fractionalPart += 1;
    }
    int32 integerPart;
    integerPart = (extract_ovf(x) << 1) + (extract_ovf(x << 1) & 1);
    if(fractionalPart == 0)
    {
        printf("%i",integerPart);
        return;
    }
    else
    {
        if(integerPart < 0)
        {
            integerPart += 1;
            fractionalPart = 1000000000 - fractionalPart;
        }
    }
    // Removing the zeroes from fractionalPart is not implemented.
    printf("%i.%i\n",integerPart,fractionalPart);
}

void main()
{
    printf_acc(0.75);
}

实施有效,但并非最佳。有什么更有效的方法来实现这一目标?

c bit fixed-point bsp
© www.soinside.com 2019 - 2024. All rights reserved.