Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Represent decimal numbers using integers

Tags:

I'm trying to come up with a way of solving my hardware limitations using software. The problem I have is that I can only write whole numbers (integers) to my hardware, but I want the luxury of using decimal-numbers when calculating results etc.

HexaDecimals with a conversion-factor came to mind here.. I can techniqually send a hex-value like (00)1105 and then just interpret that as 11.05 (E^-2) software side.

This would mean that I techniqually could handle decimal numbers software side while only sending whole numbers to my hardware.

Are there better ways of dealing with this problem? (Binary values are not an option since there is a length-limit of the messages that can be sent. (length <= 10). I will not exceed E^5 (nnnnn) for the intended use.)

This current approach has obvious problems and all approaches will likely have that but I'm curious as to what other ways this could be achieved?

Don't worry about the hardware, just consider it a black box, where integer-numbers are the only valid input.

like image 244
Joel Avatar asked Mar 21 '19 13:03

Joel


1 Answers

From what I can understand from the question, fixed points might help you. Fixed points allow you to do decimal arithmetic with integers assuming the number of digits after the decimal point is known in advance.

Here is a quick and dirty implemetation of fixed points:

#include <stdio.h>

#define FP_ABS(x) ((x) >= 0 ? (x) : -(x))

// This will determine the number of digits after the decimal point.
// It must be a power of 10.
// In this case, you can represent all the numbers in the range -2147483.648 to 2147483.647
// or if you want to be safe -2000000.000 to 2000000.000
#define FP_DECIMAL_FACTOR 1000

#define FP_LIT(x) ((int)((x) * FP_DECIMAL_FACTOR))
#define FP_ADD(x, y) ((x) + (y))
#define FP_SUB(x, y) ((x) - (y))
#define FP_MUL(x, y) ((x) * (y) / FP_DECIMAL_FACTOR)
#define FP_DIV(x, y) ((x) * FP_DECIMAL_FACTOR / (y))

#define FP_INT_PART(x) ((x) / FP_DECIMAL_FACTOR)
#define FP_DEC_PART(x) (FP_ABS((x) % FP_DECIMAL_FACTOR))


int main()
{
    int a = FP_LIT(25.01);
    int b = FP_LIT(12.2);

    printf("a = %d.%03d\n", FP_INT_PART(a), FP_DEC_PART(a));
    printf("b = %d.%03d\n", FP_INT_PART(b), FP_DEC_PART(b));

    int a_plus_b = FP_ADD(a, b);
    printf("a + b = %d.%03d\n", FP_INT_PART(a_plus_b), FP_DEC_PART(a_plus_b));

    int a_minus_b = FP_SUB(a, b);
    printf("a - b = %d.%03d\n", FP_INT_PART(a_minus_b), FP_DEC_PART(a_minus_b));

    int b_minus_a = FP_SUB(b, a);
    printf("b - a = %d.%03d\n", FP_INT_PART(b_minus_a), FP_DEC_PART(b_minus_a));

    int a_multiply_b = FP_MUL(a, b);
    printf("a * b = %d.%03d\n", FP_INT_PART(a_multiply_b), FP_DEC_PART(a_multiply_b));

    int a_divide_b = FP_DIV(a, b);
    printf("a / b = %d.%03d\n", FP_INT_PART(a_divide_b), FP_DEC_PART(a_divide_b));

    int b_divide_a = FP_DIV(b, a);
    printf("b / a = %d.%03d\n", FP_INT_PART(b_divide_a), FP_DEC_PART(b_divide_a));

    return 0;
}
like image 147
Ameen Avatar answered Sep 21 '22 03:09

Ameen