为什么Round(-0.0066219357357)返回-1?

时间:2011-10-27 09:48:42

标签: delphi

我想Round(-0.0066219357357),它会-1

不应该是0吗?我可以用什么来正确地围绕它?

更新 该数字是(LineDirection.X / distance)的结果; 其中LineDirection.X是一个整数,而Distace是double。

3 个答案:

答案 0 :(得分:9)

从XE查看System.pas,所有工作都由FISTP指令完成:

    procedure _ROUND;
    asm
      ...
            FISTP   qword ptr [ESP]
      ...
    end;

根据英特尔的Instruction Reference,根据FPU控制字的RC字段指定的舍入模式,“值”四舍五入为整数值“

因此,我建议您检查FPU控制字的 RC 字段是否设置为您需要的舍入。

您可以通过使用整个控制字来执行此操作 - 请参阅Set8087CW以及相关的xxxx8087CW过程/函数,并使用Default8087CW变量。

或者你可以尝试Math.SetRoundMode,正如@Uwe Raabe建议的那样。您的案例听起来像使用了rmUp或rmTruncate rmDown

理论上,你的CPU也是原因,但不是这样。

答案 1 :(得分:6)

来自Delphi的帮助:

  

Round的行为可能会受到Set8087CW程序或Math.SetRoundMode函数的影响。

在Delphi 2006中测试,Round和Ceil给出相同的结果:0。

答案 2 :(得分:3)

您要求人们为您排除故障。所以我可以提供以下想法:

  1. 将您的部门的值存储在double类型的变量中。

    ...
    var
      val : Double;
    begin
     val := Expression1/expression2; // use single step in debugger to evaluate and store
     val := Round(val); // now step over this value.
     ...
    
  2. 使用文字测试:

    val := Round(0.006);
    val := Round(-0.006);
    
  3. 观察一致或不一致的结果,检查并发布这些结果。请记住,这里可能会发生很多事情:

    一个。涉及哪些类型以及发生了什么重大/精确损失?

    B中。您计算中的任何位置都会出现任何整数溢出错误,而您没有考虑到这些错误吗?

    ℃。有没有人截断你没有考虑到的任何结果?

    d。特殊情况下;有人在评论中询问了另一个名为Round()的函数吗?一个Cpu问题?内存腐败?创造性地思考,你是一名程序员。在CPU视图中打开Debug-DCU并单步执行代码。确保你到达System.pas _ROUND。使用调试表达式计算器和调试监视窗口来监视变量值。搞清楚。