前回の 固定小数点の再発明 - 滴了庵日録 ではROMサイズがかえって増えるという残念な結果になったので、C++でクラス化することはあきらめてC言語で書きなおした。
fixed24.h
#ifndef _FIXED24_H
#define _FIXED24_H
#include<stdint.h>
typedef int32_t fixed24;
#define FIXED24(x, y) (fixed24)(((int64_t)(x) << 24)/(int64_t)(y))
fixed24 int_toFixed24(int32_t x, int32_t y);
fixed24 fixed24_mul(fixed24 x, fixed24 y);
fixed24 fixed24_div(fixed24 x, fixed24 y);
int fixed24_toInt(fixed24 x);
double fixed24_toDbl(fixed24 x);
#endif
fixed24.c
#include "fixed24.h"
fixed24 int_toFixed24(int32_t x, int32_t y) {
return (fixed24)(((int64_t)x << 24) / (int64_t)y);
}
fixed24 fixed24_mul(fixed24 x, fixed24 y) {
return (int32_t)(((int64_t)(x) * (int64_t)(y)) >> 24);
}
fixed24 fixed24_div(fixed24 x, fixed24 y) {
return (int32_t)((((int64_t)(x) << 32) / (int64_t)(y)) >> 8);
}
int fixed24_toInt(fixed24 x) {
return (int)((x) >> 24);
}
double fixed24_toDbl(fixed24 x) {
return (double)x / (double)0x01000000;
}
テスト
#include <stdio.h>
#include <stdlib.h>
#include "fixed24.h"
int main(void)
{
fixed24 x = FIXED24(10, 1);
fixed24 y = int_toFixed24(20, 100);
fixed24 z = 0x01000000 / 2;
printf("x = %d (%08X)\n", fixed24_toInt(x), x);
printf("y = %f (%08X)\n", fixed24_toDbl(y), y);
printf("z = %f (%08X)\n", fixed24_toDbl(z), z);
z = x + y;
printf("%f + %f = %f (%08X)\n",
fixed24_toDbl(x), fixed24_toDbl(y), fixed24_toDbl(z), z);
z = x - y;
printf("%f - %f = %f (%08X)\n",
fixed24_toDbl(x), fixed24_toDbl(y), fixed24_toDbl(z), z);
z = fixed24_mul(x, y);
printf("%f * %f = %f (%08X)\n",
fixed24_toDbl(x), fixed24_toDbl(y), fixed24_toDbl(z), z);
z = fixed24_div(x, y);
printf("%f / %f = %f (%08X)\n",
fixed24_toDbl(x), fixed24_toDbl(y), fixed24_toDbl(z), z);
z = x * 2;
printf("%f * 2 = %f (%08X)\n", fixed24_toDbl(x), fixed24_toDbl(z), z);
z = x / 2;
printf("%f / 2 = %f (%08X)\n", fixed24_toDbl(x), fixed24_toDbl(z), z);
x = FIXED24(1, 1);
y = FIXED24(1, 1);
printf("%f == %f : %s\n",
fixed24_toDbl(x), fixed24_toDbl(y), (x == y) ? "TRUE" : "FALSE");
printf("%f != %f : %s\n",
fixed24_toDbl(x), fixed24_toDbl(y), (x != y) ? "TRUE" : "FALSE");
y = FIXED24(2, 1);
printf("%f == %f : %s\n",
fixed24_toDbl(x), fixed24_toDbl(y), (x == y) ? "TRUE" : "FALSE");
printf("%f != %f : %s\n",
fixed24_toDbl(x), fixed24_toDbl(y), (x != y) ? "TRUE" : "FALSE");
return 0;
}