1. 浮點(diǎn)數(shù)正確的累加方法。
運(yùn)行下述代碼段:
double value = 99999999.99;
double sum = 0.0;
for(int i=0;i<8192;i++)
{
sum += value; // 錯(cuò)誤的浮點(diǎn)累加方法
}
printf("%18.2lf", sum); // 819199999918.02 --wrong
運(yùn)行結(jié)果,sum是錯(cuò)誤的, 和正確值相差0.06(99999999.99 * 8192 = 819199999918.08),對于報(bào)表之類的高精度的項(xiàng)目數(shù)據(jù)統(tǒng)計(jì),這是不能容忍的,循環(huán)越多誤差越大。解決方法之一,可以用高精度算法庫來代替,比如doubledouble類型,或選擇微軟的解決方法:本意是,浮點(diǎn)相加硬件實(shí)現(xiàn)是減法。把加法改成減法,把誤差也計(jì)算進(jìn)去。
上述代碼修改后:
double value = 99999999.99;
double sum = 0.0;
double C=0, Y, T;
for(int i=0;i<8192;i++)
{
Y = value - C;
T = sum + Y;
C = T - sum - Y; // 正確的浮點(diǎn)累加方法,做減法。
sum = T;
}
printf("%18.2lf", sum);// 819199999918.08 --correct
加了誤差累計(jì),這樣結(jié)果就正確了。還有浮點(diǎn)運(yùn)算法則最重要一點(diǎn),是不符合實(shí)數(shù)算法相同的代數(shù)規(guī)則。 (sum+Y)-sum-Y ,結(jié)果是不等于零的。
參考:
http://blog.csdn.net/l1t/archive/2004/10/01/122777.aspx
http://msdn.microsoft.com/en-us/library/aa289157(VS.71).aspx
---------------------------------------------------------------
2. 轉(zhuǎn)義符和字符串分離。
char* aaa1 = "e:\\12\xB2\xE2""file.txt";
char* aaa2 = "e:\\12\xB2\xE2file.txt"; // 編譯失敗, 0xE2File被識(shí)別為大字符進(jìn)行轉(zhuǎn)意。
切忌轉(zhuǎn)義符后直接跟字符串,這種錯(cuò)誤有時(shí)候編譯器通過,但結(jié)果出錯(cuò),很難查。
------------------------------------------------------------
3. 繪制unicode的surrogate pair
用TextOut可以繪制出來,直接用GetGlyphOutline會(huì)失敗,以下是通過TTF文件的筆劃ID號(hào),來繪制UCS-4的方法。
3.1 在ttf文件里,尋找代碼的筆劃ID:
uint glyphid_code = 0;
uint n;
for (n=0; n<nGroups; n++)
{
uint startCharCode = vfile.getBigEndianInt();
uint endCharCode = vfile.getBigEndianInt();
uint startGlyphID = vfile.getBigEndianInt();
uint code;
for (code = startCharCode; code <= endCharCode; code++)
{
uint w1 = 0;
uint w2 = 0;
// http://en.wikipedia.org/wiki/UTF-16/UCS-2
if (code > 0x10000)
{
uint v = code;
uint v1 = v - 0x10000;
uint vh = v1 >> 10;
uint vl = v1 & 0x3FF;
w1 = 0xD800 + vh;
w2 = 0xDC00 + vl;
}
if (w1 == 0xD842 && w2 == 0xDF9F)
glyphid_code = (code - startCharCode) + startGlyphID;
}
}
3.2. 用筆劃ID(glyphid_code)來直接繪制UCS-4文字.
---------------------
// must use GGO_GLYPH_INDEX
DWORD bufsize = GetGlyphOutline(hdc, glyphid_code, GGO_NATIVE|GGO_GLYPH_INDEX, &gm, 0, 0, &mat);
if (bufsize == 0 || bufsize == GDI_ERROR)
{
DWORD err = GetLastError();
continue;
}
byte* bufdata = new byte[bufsize];
if (GetGlyphOutline(hdc, r_glyphid_code, GGO_NATIVE|GGO_GLYPH_INDEX, &gm, bufsize, bufdata, &mat) == GDI_ERROR)
{
delete[] bufdata;
}
------------------------------------------------------------
4. 代碼優(yōu)化:
1. 在成員函數(shù)里,使用靜態(tài)數(shù)組,避免每次都需要初始化。
2. 在IF判斷時(shí),使用likely/unlikely。
3. 減少malloc調(diào)用消耗,特別是算法循環(huán)中(比如RSA大數(shù)算法),使用stack代替。
------------------------------------------------------------
在VC里整合使用intel c compiler的好處:
1. 檢查std::string str; printf("%s", str); 此類的致命錯(cuò)誤;// non-POD (Plain Old Data) class type passed through ellipsis
2. 使用OpenMP優(yōu)化代碼
------------------------------------------------------------
性能:
1. 圖片內(nèi)存隨機(jī)訪問,在release模式下,data[y][x]二維數(shù)組訪問和data[y*width+x]一維數(shù)組是一樣快的,編譯器會(huì)自動(dòng)優(yōu)化乘法。