How to write a fixed point function?
I would like to ask how to use fixed point in the linux kernel because the two functions, kernel_fpu_begin() and kernel_fpu_end(), does not work. So another method for solving this floating number is to use fixed point. My partner and I talked about this and we came upon to this function.
Code:
/*new "fixed" function -----------------------------------------*/global int cy; //comment: use global variable cy . I am still having trouble understanding this function. Okay so you take the values x and y and multiple the values okay. I do not see how this help for floating numbers. The code below looks exactly the same as the fixed point function. So how is this possible if I cannot use decimals/floating numbers? Code:
avgRTT = ((255/256)*avgRtt) + ((1/256)*rtt); Thanks |
Confused I am......
In my book, "fixed point" and "integer" are not the same thing. You are declaring and integer data type, which means there is NO decimal point. C also has a "float" data type------does it also have a "fixed" data type?----I don't remember. |
Perhaps an illustrated example will help you understand.
Consider the linear blending function Code:
float blend(const float x, const float y0, const float y1) To use fixed-point math, you scale the floating-point value by a fixed integer S . So, instead of 0 to 1, integer x would get integer values from 0 to S . When multiplying two fixed-point values, you must divide the result by S, because Code:
S * x * y = (S * x) * (S * y) / S Code:
(S * x) * (S * y) / S = trunc( ( trunc(S * x) * trunc(S * y) ) / S ) with integers Code:
( ( x * y ) / 256 ) * 256 * 256 ) = trunc(x * y / 256) * 256 * 256 != 256 * x * y with integers Finally, this code may not work with optimizations disabled: Code:
avgRTT = ((255/256)*avgRtt) + ((1/256)*rtt); Code:
avgRTT = (trunc(255/256) * avgRtt) + (trunc(1/256) * rtt); Without explicit casts, C compilers may always reorder the order of the operations, as long as no precision is lost. They will never evaluate x*y/256 as trunc(x/256)*y . When optimizations are disabled, the C compiler may not reorder the operations at all. Explicit casts (in C99) require the compiler to evaluate the expression so that the cast part is limited to the precision of the cast type; i.e. (int)(x/256)*y will always be equivalent to trunc(x/256)*y in C99, regardless of optimization flags. When the multiplication and division are done in the correct order, Code:
avgRTT = (255 * avgRtt + rtt) / 256; Code:
avgRtt = trunc(trunc(trunc(255 * avgRtt) + rtt) / 256); Returning back to the initial blending function: Assume x varies between 0 and 255, with scale factor S = 256, i.e. 256 = 1.0, and that we assume both y0 and y1 are integers that can be multiplied by 256 without overflowing. Then, Code:
int blend(const int x, const int y0, const int y1) Finally, we can optimize away one multiplication in both floating-point and integer cases. The end result is actually more numerically stable (for floats), too: Code:
float blendf(const float x, const float y0, const float y1) { return y0 + x * (y1 - y0); } Code:
int blend(const int x, const int one, const int y0, const int [I]y1[I]) Also note that all the variables above are either floats or (scaled) integers; I am not using any special fixed-point types at all. I am just using fixed-point arithmetic. Did this help? |
All times are GMT -5. The time now is 12:14 PM. |