zoukankan      html  css  js  c++  java
  • 取整函数

    一、函数说明

    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;

    }

     

  • 相关阅读:
    C++ 的查漏补缺
    Model元数据解析
    Controller
    路由
    win8系统 Reflect 破解
    MVC运行原理
    源代码Log
    linq 分类
    EF 实体关系
    第二十六章 计算限制的异步操作
  • 原文地址:https://www.cnblogs.com/hanford/p/6177926.html
Copyright © 2011-2022 走看看