yarf 0.1
Yet Another RepRap Firmware
|
00001 /* 00002 * fixed_point.h 00003 * 00004 * Copyright 2011 Pieter Agten 00005 * 00006 * This file is part of Yarf. 00007 * 00008 * Yarf is free software: you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation, either version 3 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * Yarf is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with Yarf. If not, see <http://www.gnu.org/licenses/>. 00020 */ 00021 00031 #ifndef FIXED_POINT_H 00032 #define FIXED_POINT_H 00033 00034 #include <stdint.h> 00035 00039 #define NB_FRACTIONAL_BITS 16 00040 00044 #define FRACTIONAL_MULTIPLIER 65536.0f 00045 00049 #define FXP_16U16_MAX UINT32_MAX 00050 00054 #define FXP_16U16_ZERO 0 00055 00059 #define FXP_16U16_ONE ((fxp16u16_t)1 << NB_FRACTIONAL_BITS) 00060 00064 #define FXP_16U16_ONE_HALF (FXP_16U16_ONE >> 1) 00065 00069 typedef uint32_t fxp16u16_t; 00070 00071 00081 inline uint16_t 00082 fxp16u16_to_uint16(fxp16u16_t x) 00083 { 00084 return (x + FXP_16U16_ONE_HALF) >> NB_FRACTIONAL_BITS; 00085 } 00086 00093 inline float 00094 fxp16u16_to_float(fxp16u16_t x) 00095 { 00096 return ((float)x / FRACTIONAL_MULTIPLIER); 00097 } 00098 00106 inline fxp16u16_t 00107 fxp16u16_from_uint16(uint16_t x) 00108 { 00109 return ((fxp16u16_t)x) << NB_FRACTIONAL_BITS; 00110 } 00111 00120 inline fxp16u16_t 00121 fxp16u16_from_float(float x) 00122 { 00123 return (fxp16u16_t)((x * FRACTIONAL_MULTIPLIER) + 0.5f); 00124 } 00125 00126 00138 inline fxp16u16_t 00139 fxp16u16_from_float_s(float x) 00140 { 00141 if (x >= fxp16u16_to_float(FXP_16U16_MAX)) { 00142 return FXP_16U16_MAX; 00143 } else if (x < 0) { 00144 return FXP_16U16_ZERO; 00145 } else { 00146 return fxp16u16_from_float(x); 00147 } 00148 } 00149 00150 00160 inline fxp16u16_t 00161 fxp16u16_mul(fxp16u16_t x, fxp16u16_t y) 00162 { 00163 uint64_t result = ((uint64_t)x * (uint64_t)y); 00164 result += FXP_16U16_ONE_HALF; 00165 return (fxp16u16_t)(result >> NB_FRACTIONAL_BITS); 00166 } 00167 00175 inline fxp16u16_t 00176 fxp16u16_div(fxp16u16_t x, fxp16u16_t y) 00177 { 00178 uint64_t temp = (uint64_t)x << NB_FRACTIONAL_BITS; 00179 temp += (y >> 1); // For correct rounding 00180 return (fxp16u16_t)(temp / y); 00181 } 00182 00191 inline fxp16u16_t 00192 fxp16u16_div_uint16(fxp16u16_t x, uint16_t y) 00193 { 00194 uint64_t temp = (uint64_t)x; 00195 temp += (y >> 1); // For correct rounding 00196 return (fxp16u16_t)(temp / y); 00197 } 00198 00205 inline fxp16u16_t 00206 fxp16u16_square(fxp16u16_t x) 00207 { 00208 return fxp16u16_mul(x,x); 00209 } 00210 00211 #endif //FIXED_POINT_H