2017年9月13日 星期三

Some little trick in C.


1.Exchange two variable without extra memory space.
    Since A xor A = 0 , so A xor A xor B = B thus we can change this two variable by use xor op.
2.String compose.
   By use #define fun(a,b) a##b  we can easily to compose a in a string.
3.Use union to transform float to 4-char raw data
   union define two different data type in same memory space(Ref 3)
union {
float f;
char c[4];
}var;
float floata = 1.234;
var.f = floata;// c[0...3] contain floata data the sequence depend on big/little endian cpu
view raw gistfile1.txt hosted with ❤ by GitHub
4.Counting the number of args
 
#define NUM_VA_ARGS_IMPL( \
_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
_11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
_21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
_31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
_41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
_51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \
_61, _62, N, ...) N
#define NUM_VA_ARGS(...) NUM_VA_ARGS_IMPL(__VA_ARGS__, 63, 62, 61, \
60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \
50, 49, 48, 47, 46, 45, 44, 43, 42, 41, \
40, 39, 38, 37, 36, 35, 34, 33, 32, 31, \
30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \
20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \
10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
view raw gistfile1.txt hosted with ❤ by GitHub
    If we call NUM_VA_ARGS(1, 2, 3) will turn out to 

    NUM_VA_ARGS_IMPL( 1, 2,  3, 63, 62, 61,  \
             60, 59, 58, 57, 56, 55, 54, 53, 52, 51,                         \
             50, 49, 48, 47, 46, 45, 44, 43, 42, 41,                         \
             40, 39, 38, 37, 36, 35, 34, 33, 32, 31,                         \
             30, 29, 28, 27, 26, 25, 24, 23, 22, 21,                         \
             20, 19, 18, 17, 16, 15, 14, 13, 12, 11,                         \
             10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
     The blue part is the ... variable and the red part is the N so that we can get the count of args.
5.Define how many bits use to represent the variable in struct.
   Consider we have a struct represent 32 bits register and have 0~7 bits for data transfer, 8~31 bits
   for reserve.We can declare a struct like
struct
{
uint32_t data:8;
uint32_t _reserve:24;
} b;
view raw gistfile1.txt hosted with ❤ by GitHub
So that if we give the data value above 255 than compiler will warning us the value is over the range of this variable can represent.

6.Compare unsigned value to constant value use minus replace compare

#define PACKET_MAX 100
unsigned int packet_count ;
/*if use this compiler will give a warring */
if(packet_count >=PACKET_MAX)
/*use this for alternative */
if(PACKET_MAX - packet_count >=0)
view raw gistfile1.txt hosted with ❤ by GitHub
7.Define constant in struct and integer trick.

/**@brief HAL RTC Time data struct
*/
typedef struct {
uint8_t year; /**< Year value, range between 00 ~ 99 (represend 2000 ~ 2099) */
uint8_t month; /**< Month value, range between 1 ~ 12 */
uint8_t day; /**< Day value, range between 1 ~ 31 */
uint8_t hour; /**< Hour value, range between 0 ~ 23 */
uint8_t minute; /**< Minute value, range between 0 ~ 59 */
uint8_t second; /**< Second value, range between 0 ~ 59 */
hal_rtc_time_scale_t time_scale;/**< Time scale @ref hal_rtc_time_scale_t */
#define HAL_RTC_MODULE_VERSION 0.0.1; // Define constant in struct
} hal_rtc_time_data_t;
int time = 123e3; // Equal to 123000
view raw gistfile1.txt hosted with ❤ by GitHub
Ref:
      1.Linux C编程一站式学习
      2.C語言:浮點數通信傳輸
      3.Union型別 (討論在C&C++中的差異)
      4.nRF52 SDK/nrf_log.h
      5.C - Bit Fields
      6.https://stackoverflow.com/questions/514118/how-does-duffs-device-work


   

2017年9月5日 星期二

A fast method to round a double to a 32-bit int explained note

Quote:

Between 2^52=4,503,599,627,370,496 and ^253=9,007,199,254,740,992 the representable numbers are exactly the integers
This follows from the fact that the mantissa is 52 bits wide.

The other interesting fact about adding 2^51+2^52 is that it affects the mantissa only in the two highest bits - which are discarded anyway, since we are taking only its lowest 32 bits.



IEEE 754 Double Floating Point Format.svg








So we add 2^51+2^52 and get the lowest 32 bits via a cast than we can get the integer from double.

#define double2int(i, d) \
    {double t = ((d) + 6755399441055744.0); i = *((int *)(&t));}

Ref:
      1. A fast method to round a double to a 32-bit int explained
      2. Double-precision floating-point format

Linux driver: How to enable dynamic debug at booting time for built-in driver.

 Dynamic debug is useful for debug driver, and can be enable by: 1. Mount debug fs #>mount -t debugfs none /sys/kernel/debug 2. Enable dy...