前言
庖丁解牛 - <<庄子>>
庖丁为文惠君解牛,
手之所触, 肩之所倚, 足之所履, 膝之所踦, 砉然向然, 奏刀騞然, 莫不中音, 合于《桑林》之舞, 乃中《经首》之会.
文惠君曰:"嘻, 善哉! 技盍至此乎?"
庖丁释刀对曰:"臣之所好者, 道也, 进乎技矣.
始臣之解牛之时, 所见无非牛者.
三年之后, 未尝见全牛也.
方今之时, 臣以神遇而不以目视, 官知止而神欲行.
依乎天理, 批大郤, 导大窾, 因其固然, 技经肯綮之未尝, 而况大軱乎!
良庖岁更刀, 割也; 族庖月更刀, 折也. 今臣之刀十九年矣, 所解数千牛矣, 而刀刃若新发于硎.
彼节者有间, 而刀刃者无厚;以无厚入有间, 恢恢乎其于游刃必有余地矣!
是以十九年而刀刃若新发于硎.
虽然, 每至于族, 吾见其难为, 怵然为戒, 视为止, 行为迟.
动刀甚微, 謋然已解, 如土委地.
提刀而立, 为之四顾, 为之踌躇满志, 善刀而藏之."
文惠君曰:"善哉, 吾闻庖丁之言, 得养生焉."
庖丁为文惠君解牛,
手之所触, 肩之所倚, 足之所履, 膝之所踦, 砉然向然, 奏刀騞然, 莫不中音, 合于《桑林》之舞, 乃中《经首》之会.
文惠君曰:"嘻, 善哉! 技盍至此乎?"
庖丁释刀对曰:"臣之所好者, 道也, 进乎技矣.
始臣之解牛之时, 所见无非牛者.
三年之后, 未尝见全牛也.
方今之时, 臣以神遇而不以目视, 官知止而神欲行.
依乎天理, 批大郤, 导大窾, 因其固然, 技经肯綮之未尝, 而况大軱乎!
良庖岁更刀, 割也; 族庖月更刀, 折也. 今臣之刀十九年矣, 所解数千牛矣, 而刀刃若新发于硎.
彼节者有间, 而刀刃者无厚;以无厚入有间, 恢恢乎其于游刃必有余地矣!
是以十九年而刀刃若新发于硎.
虽然, 每至于族, 吾见其难为, 怵然为戒, 视为止, 行为迟.
动刀甚微, 謋然已解, 如土委地.
提刀而立, 为之四顾, 为之踌躇满志, 善刀而藏之."
文惠君曰:"善哉, 吾闻庖丁之言, 得养生焉."
测试代码(258.369double值转科学计数法)
/// @file PositiveFloat.cpp
/// @brief 将258.369 double值转为内存表示(科学计数法)
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[]) {
/// 内存中是小端摆放
/// 4070,25E0,0000,0000
unsigned char cBuf[8] = {0x00, 0x00, 0x00, 0x00, 0xe0, 0x25, 0x70, 0x40};
unsigned short usBuf[4] = {0x0, 0x0, 0x25e0, 0x4070};
double* pdbl = NULL;
pdbl = (double*)cBuf;
printf("%f\n", *pdbl); ///< 258.367188
pdbl = (double*)usBuf;
printf("%f\n", *pdbl); ///< 258.367188
return 0;
}
/**
double值在内存中是8个字节(64bits)
S = 1bits, (258.369是正数, S = 0)
E = 11bits
D = 52bits
258.369 double值转内存值
整数部分转2进制表示
258 / 2
129 0
129 / 2
64 1
64 / 2
32 0
32 / 2
16 0
16 / 2
8 0
8 / 2
4 0
4 / 2
2 0
2 / 2
1 0
整数部分的2进制表示为(从最后一个商念到第一个油余数)
100000010
小数部分转2进制表示(最多只算出8位小数的表示)
0.369 * 2
0.738 0
0.738 * 2
1.476
0.476 1
0.476 * 2
0.952 0
0.952 * 2
1.904
0.904 1
0.904 * 2
1.808
0.808 1
0.808 * 2
1.616
0.616 1
0.616 * 2
1.232
0.232 1
0.232 * 2
0.464 0
小数部分的2进制表示(从第一个进位念到最后一个进位)
.01011110
整数 + 小数部分为
100000010.01011110 * 2^0
1.0000001001011110 * 2^8
D = 0000001001011110 (不算整数部分的1)
E = 1023 + 8 (2^8的指数值)
= 1031
= 100,0000,0111
= 10000000111
E值的2进制表示
1031 / 2
515 1
515 / 2
257 1
257 / 2
128 1
128 / 2
64 0
64 / 2
32 0
32 / 2
16 0
16 / 2
8 0
8 / 2
4 0
4 / 2
2 0
2 / 2
1 0
从最后一个商念到第一个余数
100,0000,0111
拼装SED
0,10000000111,0000001001011110
补齐D部分的0(52-16 = 36, 要补36个0)
0,10000000111,0000,0010,0101,1110,0000,0000,0000,0000,0000,0000,0000,0000,0000
最后的拼装结果
0100000001110000001001011110000000000000000000000000000000000000
将拼装结果变成16进制
0100,0000,0111,0000,0010,0101,1110,0000,0000,0000,0000,0000,0000,0000,0000,0000
4 0 7 0 2 5 E 0 0 0 0 0 0 0 0 0
407025E000000000
4070,25E0,0000,0000
16进制对照表
0000 = 0 0001 = 1 0010 = 2 0011 = 3
0100 = 4 0101 = 5 0110 = 6 0111 = 7
1000 = 8 1001 = 9 1010 = A 1011 = B
1100 = C 1101 = D 1110 = E 1111 = F
*/
测试代码(-258.369double值转科学计数法)
/// @file PositiveFloat.cpp
/// @brief 将-258.369 double值转为内存表示(科学计数法)
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[]) {
/// 内存中是小端摆放
/// C070,25E0,0000,0000
unsigned char cBuf[8] = {0x00, 0x00, 0x00, 0x00, 0xe0, 0x25, 0x70, 0xC0};
unsigned short usBuf[4] = {0x0, 0x0, 0x25e0, 0xC070};
double* pdbl = NULL;
pdbl = (double*)cBuf;
printf("%f\n", *pdbl); ///< -258.367188
pdbl = (double*)usBuf;
printf("%f\n", *pdbl); ///< -258.367188
return 0;
}
/**
double值在内存中是8个字节(64bits)
S = 1bits, (-258.369是负数, S = 1)
E = 11bits
D = 52bits
258.369 double值转内存值
整数部分转2进制表示
258 / 2
129 0
129 / 2
64 1
64 / 2
32 0
32 / 2
16 0
16 / 2
8 0
8 / 2
4 0
4 / 2
2 0
2 / 2
1 0
整数部分的2进制表示为(从最后一个商念到第一个油余数)
100000010
小数部分转2进制表示(最多只算出8位小数的表示)
0.369 * 2
0.738 0
0.738 * 2
1.476
0.476 1
0.476 * 2
0.952 0
0.952 * 2
1.904
0.904 1
0.904 * 2
1.808
0.808 1
0.808 * 2
1.616
0.616 1
0.616 * 2
1.232
0.232 1
0.232 * 2
0.464 0
小数部分的2进制表示(从第一个进位念到最后一个进位)
.01011110
整数 + 小数部分为
100000010.01011110 * 2^0
1.0000001001011110 * 2^8
D = 0000001001011110 (不算整数部分的1)
E = 1023 + 8 (2^8的指数值)
= 1031
= 100,0000,0111
= 10000000111
E值的2进制表示
1031 / 2
515 1
515 / 2
257 1
257 / 2
128 1
128 / 2
64 0
64 / 2
32 0
32 / 2
16 0
16 / 2
8 0
8 / 2
4 0
4 / 2
2 0
2 / 2
1 0
从最后一个商念到第一个余数
100,0000,0111
拼装SED
1,10000000111,0000001001011110
补齐D部分的0(52-16 = 36, 要补36个0)
1,10000000111,0000,0010,0101,1110,0000,0000,0000,0000,0000,0000,0000,0000,0000
最后的拼装结果
1100000001110000001001011110000000000000000000000000000000000000
将拼装结果变成16进制
1100,0000,0111,0000,0010,0101,1110,0000,0000,0000,0000,0000,0000,0000,0000,0000
C 0 7 0 2 5 E 0 0 0 0 0 0 0 0 0
C07025E000000000
C070,25E0,0000,0000
16进制对照表
0000 = 0 0001 = 1 0010 = 2 0011 = 3
0100 = 4 0101 = 5 0110 = 6 0111 = 7
1000 = 8 1001 = 9 1010 = A 1011 = B
1100 = C 1101 = D 1110 = E 1111 = F
*/