问题是这样的,我通过计算得出的数值有3位小数,现在的情况是:如果该数值小于200,那么保留一位小数,取舍原则就是4舍6入5考虑,也就是说如果小数点的第二位是大于等于6的话就直接进位,如果是等于5,那么要看第三位小数,如果第三位小数是奇数就进上,如果是偶数就舍去,经过这样处理后的第二位小数如果是6的时候就进到第一位小数,如果还是5那就舍去,然后再取整,如果该数值大于200并小于等于1000时,该数值只保留到5的倍数,如果大于1000,就保留到10的倍数,我举例如下:
198.505修约后为198
198.515修约后为199
202修约后为200
206修约后为205
1025修约后为1020
1026修约后为1030
这样程序怎样实现?谢谢!

解决方案 »

  1.   

    floor 和 ceil 是 math unit 里的函数,使用前要先 Uses Math。
      trunc 和 round 是 system unit 里的函数,缺省就可以用。
       floor 直接往小的取,比如 floor(-123.55)=-124,floor(123.55)=123
       trunc 直接切下整数,比如 trunc(-123.55)=-123, floor(123.55)=123
       ceil 直接往大的取,比如 ceil(-123.55)=-123, ceil(123.55)=124
       round 计算四舍五入,比如 round(-123.55)=-124,round(123.55)=124小于200, 就只要用函数就可以了
    大于200并小于等于1000时, integer MOD 10 得到尾数,然后根据你的原则处理
       if 尾数 〉5 then integer := (integer  DIV 10)*10 + 5 else
       if 尾数 < = 5 then integer := integer - 尾数 ;
    如果大于1000, integer := (integer  DIV 10)*10 具体情况你自己处理
      

  2.   

    >>回复人: plutu(菜根谭) ( ) 信誉:100  2004-08-06 17:12:00  得分: 0  
     
     
    >>   哈哈,我估计大家看了就会晕,我第一次看到时也晕了,但现实的情况就是要求这样,>>算法是很明确了,但关键是小数的怎样取,怎样直接就取到第三位小数或第二位小数?我的>>意思是不用乘以100或1000这样来取把数字当作字符传处理
    pos 取到小数点,然后根据你的算法判断  
     
      

  3.   

    to nyf1220(我是党员) :这样类型转来转去我觉得不是很好,我觉得应该有更好的方法
      

  4.   

    不算来回转吧??
    处理的时候当字符穿,
    处理完直接strtoint就ok了,
      

  5.   

    呵呵,和我以前问的问题一样,
    最后也是别人帮我解决的,函数如下
    const
      CC_SIGNIFICANT_DIGIT = 15;  //Double类型的有效位数为15(包括小数)type
      TReserveDigitRang = 1..CC_SIGNIFICANT_DIGIT;{ /**************************************************
       * 说明:                                         *
       *       功能同Math单元的RoundTo函数              *
       * 参数:                                         *
       *       同Math单元的RoundTo函数                  *
       * 返回:                                         *
       *       同Math单元的RoundTo函数                  *
       * 备注:                                         *
       *       原Math单元中的RoundTo函数精度导致问题    *
       *       比如,AValue = 0.0255, ADigit = -3       *
       *       则 AValue / 0.001 实际等于25.49999999... *
       *       这样Round后就等于25而不是26了            *
       *************************************************/ }
    function RoundToEx(const AValue: Double; const ADigit: TRoundToRange): Double;
    var
      LFactor: Double;
    begin
      LFactor := IntPower(10, ADigit);  //现有的算法
      //RoundToEx(0.0255, -3) = 0.026
      Result := AValue / LFactor;
      Result := Trunc(Result * 1000000 + 0.5) / 100; //因为最多只会取到判断位后的两位
      Result := Round(Result) * LFactor;  //原有的算法
      //RoundToEx(0.0255, -3) = 0.025
      //Result := Round(AValue / LFactor) * LFactor;
    end;{ /******************************************************
       * 说明:                                             *
       *       获取指定值在保留指定有效数字后的值(四舍六入) *
       * 参数:                                             *
       *       [ in]AValue 参与的指定值                     *
       *       [ in]ADigit 所保留有效数字的个数             *
       * 返回:                                             *
       *       期望值                                       *
       *****************************************************/ }
    function GetReserveValue(
      const AValue: Double; const ADigit: TReserveDigitRang): Double;
    var
      iIntPart: Integer;
      iIntLen: Integer;
    begin
      iIntLen := 0;
      iIntPart := Trunc(Abs(AValue));
      if iIntPart > 0 then
        iIntLen := Length(IntToStr(iIntPart));  Result := RoundToEx(AValue, iIntLen - ADigit);
    end;如果该数值大于200并小于等于1000时,该数值只保留到5的倍数,至于这个,你再修改一下好了,不是很难,上面的函数能解决其它问题。我用了
      

  6.   

    上面的这段错了
      Result := Trunc(Result * 1000000 + 0.5) / 100; //因为最多只会取到判断位后的两位
    应该改为
      Result := Trunc(Result * 100 + 0.5) / 100; //因为最多只会取到判断位后的两位
    其实你的这个不是很标准的银行家算法,
    如果是标准的,它不只是判断5后面的那位是不是0,只要后面有不是0的数字,都应该进1,
    上面的是按照你的标准做的,至于其它你可以控制上面函数的100,根据你判断的准确率来控制,我以前是控制到小数点后面第九位。
    你自己先修改修改
    const
      CC_SIGNIFICANT_DIGIT = 15;  //Double类型的有效位数为15(包括小数)type
      TReserveDigitRang = 1..CC_SIGNIFICANT_DIGIT;
    function RoundToEx(const AValue: Double; const ADigit: TRoundToRange): Double;
    var
      LFactor: Double;
    begin
      LFactor := IntPower(10, ADigit);
      Result := AValue / LFactor;
      Result := Trunc(Result * 100 + 0.5) / 100; //因为最多只会取到判断位后的两位
      Result := Round(Result) * LFactor;
    end;function GetReserveValue(
      const AValue: Double; const ADigit: TReserveDigitRang): Double;
    var
      iIntPart: Integer;
      iIntLen: Integer;
    begin
      iIntLen := 0;
      iIntPart := Trunc(Abs(AValue));
      if iIntPart > 0 then
        iIntLen := Length(IntToStr(iIntPart));  Result := RoundToEx(AValue, iIntLen - ADigit);
    end;