取整函數


一、函數說明

double 而言,取整、取余的相關函數和運算符請參考下表:

VB6.0

C 

C# 

Int(x)

floor(x)

Math.Floor(x)

floor表示地板,也就是將向下取整數,即返回最大的整數使得

Math.Floor(1.9)        返回    1

Math.Floor(1.0)        返回    1

Math.Floor(-1.0)        返回    -1

Math.Floor(-1.3)        返回    -2

Math.Floor(-1.9)        返回    -2

 

ceil(x)

Math.Ceiling(x)

ceil表示天花板,也就是將向上取整數,即返回最小的整數使得

Math.Ceiling(1.9)    返回    2

Math.Ceiling(1.3)    返回    2

Math.Ceiling(1.0)    返回    1

Math.Ceiling(-1.0)    返回    -1

Math.Ceiling(-1.9)    返回    -1

Fix(x)

 

Math.Truncate(x)

表示取的整數部分

Math.Truncate(1.9)    返回    1

Math.Truncate(1.0)    返回    1

Math.Truncate(-1.0)    返回    -1

Math.Truncate(-1.9)    返回    -1

Round(x)

 

Math.Round(x,...)

表示四舍五入,如:四舍五入取整

Math.Round(1.9)        返回    2

Math.Round(1.5)        返回    2

Math.Round(1.3)        返回    1

Math.Round(1.0)        返回    1

Math.Round(-1.0)    返回    -1

Math.Round(-1.3)    返回    -1

Math.Round(-1.5)    返回    -2

Math.Round(-1.9)    返回    -2

x Mod y

fmod(x,y)

x % y

返回 x / y 的余數,其符號與 x 一致。

C語言里 % 只能用於整型變量

注意:VB6.0會對結果四舍五入取整

x / y 

x / y 

x / y 

返回 x / y,對於整數而言,將舍去小數部分。

1、詳述Math.Round

Math.Round 還有更豐富的功能

①精確到小數點后n

如:Math.Round(x,n) 表示對 x 只取小數點后 n 位,多余部分四舍五入。

②四舍五入問題

四舍是一定的,但對於五到底入還是不入呢?Math.Round是可以通過MidpointRounding來進行控制的。

MidpointRounding.AwayFromZero 表示五入,這是默認的方法,如:

Math.Round(1.5,MidpointRounding.AwayFromZero);    返回 2

Math.Round(-1.5,MidpointRounding.AwayFromZero);    返回 -2

MidpointRounding.ToEven 就比較有意思了,如果5前面的數字是奇數則入,否則就舍去。如:

Math.Round(2.5,MidpointRounding.ToEven);    返回 2

Math.Round(1.5,MidpointRounding.ToEven);    返回 2

Math.Round(-1.5,MidpointRounding.ToEven);    返回 -2

Math.Round(-2.5,MidpointRounding.ToEven);    返回 -2

二、函數關系

1floorceil的關系

floor(x) = -ceil(-x),同樣的ceil(x)=-floor(-x)VB6.0里沒有ceil函數,就可以用 -Int(-x) 來代替。

2Math.Truncate floorceil的關系

Math.Truncate(x) =

寫成C語言代碼就是

double Truncate(double x)

{

if(x >= 0.0)

{

return floor(x);

}

return ceil(x); //-floor(-x)

}

三、應用

1、歸化角度

如:手表的秒針1分鍾走1圈。分鍾之后,它與起始位置的夾角是多少?顯然這個角度等於度。現在要把這個角度歸化到之間。即找到一個整數,使得成立。只考慮不等式的左半部分,則有,即。顯然這個夾角應該是

同樣的,判斷經度是否在經度和經度之間(只考慮劣弧,不考慮優弧),不能使用。如:經度180在經度-179和經度179之間,但它不滿足-179 < 180 < 179。應該使用下式判斷

函數Angle360(x)將返回角度n是一個整數),且返回值在之間。顯然,因此Angle360函數的C代碼如下:

double Angle360(double x)

{

return x - floor(x / 360.0) * 360.0;

}

2、擴展fmod函數

上述問題里,將角度歸化到之間可以使用fmod(360.0 * x,360.0);C#里可以使用(360.0 * x) % 360.0)。但是,使用fmod感覺不太方便——它的返回值符號與第一個參數的符號相同。也就是說 x 小於零,則返回值將在之間。因此有必要擴展fmod函數。

fmod(x,y)的實質是找到合適的整數,使得,然后返回余數

如果需要余數,則

如果需要余數,則

如果需要求絕對值最小的余數,則

fmod函數的模擬代碼如下

double fmod(double x,double y)

{

y = fabs(y);

if(x >= 0.0)

{

y = x - y * floor(x / y);

}

else

{

y = x - y * ceil(x / y);

}

return y;

}

fmod函數的擴展代碼如下

/****************************************************************\

x / y 的余數

nFlag    [in]        1    返回的余數大於等於零

                -1    返回的余數小於等於零

                2    返回絕對值最小的余數,若同時出現 ±(y / 2) 則取正值

                -2    返回絕對值最小的余數,若同時出現 ±(y / 2) 則取負值

                0     2 相同

\****************************************************************/

double fmodEx(double x,double y,int nFlag)

{

y = fabs(y);

if(nFlag < -2)

{

nFlag = -2;

}

else if(nFlag > 2)

{

nFlag = 2;

}

switch(nFlag)

{

case 1://返回的余數大於等於 0

y = x - y * floor(x / y);

break;

case -1://返回的余數小於等於 0

y = x - y * ceil(x / y);

break;

case -2://返回的絕對值最小的余數,優先考慮 - y / 2

y = x - y * floor(x / y + 0.5);

break;

default://返回的絕對值最小的余數,優先考慮 + y / 2

y = x - y * ceil(x / y - 0.5);

break;

}

return y;

}

3、格點

現在要在區間之間插入若干點,其中n是一個整數,d是一段固定的距離(只考慮正值),如:100米、1000米……

計算的時候要注意,不要寫 for(double n = ceil(a/d);n <= floor(b/d);n++) 這樣的代碼,因為double是有誤差的,這樣會導致誤差積累。應該這樣:

double    n0        =    ceil(a/d);

double    x0        =    n0 * d;

int        nMax    =    (int)(floor(b/d) - n0 + 0.1);

double    x;

for(int i = 0;i <= nMax;i++)

{

    x    =    x0 + i * d;

}

下面的函數專門用來獲取格點

/**********************************************************\

獲取區間[a,b]之間的格點,格點坐標是 d 的整數倍

x0        [out]    返回起始格點。

                 d 大於零,x0 是坐標最小的格點

                 d 小於零,x0 是坐標最大的格點

返回:獲得格點的個數 nCount

格點坐標為 x0 + n * dn = 0,1,2,...nCount - 1

\**********************************************************/

long GetLatticePoints(double a,double b,double d,double*x0)

{

long nCount = 0; //格點個數

double nMin; //n 的最小值

double nMax; //n 的最大值

 

a /= d;

b /= d;

if(a > b)

{

double t;

t = a;

a = b;

b = t;

}

nMin = ceil(a);

nMax = floor(b);

if(nMax >= nMin)

{

nCount = (long)(nMax - nMin + 1.1);

if(x0)

{

*x0 = nMin * d;

}

}

return nCount;

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM