I am trying to write a C (with CoolFlux BSP32) program which takes as input an accumulator and displays its decimal value. For example for an acc with the value in hexadecimal FF C000 0000, I want to print "-1.5".

The fractional value needs to be calculated with an error less than 10^(-9), so I need to use 30 bits from the fractional part of the accumulator.

I have tried to reconstruct the fractional part by using a sequence of numbers equal to 10 ^ 9 / 2 ^ current_index if 1 / 2 ^ current_index can be represented in 30 bits, and (10 ^ 9 / 2 ^ (current_index - 1)) - 1) / 2 if 1 / 2 ^ index can not be represented in 30 bits.

Reproduction of the code:

#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);
}

The implementation works, but is not optimally. What is a more efficient way to achieve this?

0

There are 0 best solutions below