前回の 固定小数点の再発明 - 滴了庵日録 では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); // 10/1 = 10 fixed24 y = int_toFixed24(20, 100); // 20/100 = 0.20 fixed24 z = 0x01000000 / 2; // 1/2 = 0.5 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; }