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?