Delphi 四舍五入一种货币

Delphi 四舍五入一种货币,delphi,delphi-xe,rounding,truncation,Delphi,Delphi Xe,Rounding,Truncation,我有以下代码来对货币进行四舍五入 function MyRound(value :currency) : integer; begin if value > 0 then result := Trunc(value + 0.5) else result := Trunc(value - 0.5); end; 到目前为止,它运行得很好,我现在的问题是,如果我想对99999989000.40这样的货币进行四舍五入,它会给出负值,因为Truc取int,MyRound也

我有以下代码来对货币进行四舍五入

function MyRound(value :currency) : integer;

begin
  if value > 0 then
    result := Trunc(value + 0.5)
  else
    result := Trunc(value - 0.5);
end;
到目前为止,它运行得很好,我现在的问题是,如果我想对99999989000.40这样的货币进行四舍五入,它会给出负值,因为Truc取int,MyRound也返回int


我可能的解决方案是将货币转换为字符串,并在之前获取字符串,然后将字符串转换回货币。这是正确的方法吗?我是delpi的新手,所以请帮我解决。

你把事情弄得太复杂了。您只需使用
Round

program Project1;
{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  C: Currency;

begin
  C := 999999989000.4;
  Writeln(Round(C));
  C := 999999989000.5;
  Writeln(Round(C));
  C := 999999989000.6;
  Writeln(Round(C));
  C := 999999989001.4;
  Writeln(Round(C));
  C := 999999989001.5;
  Writeln(Round(C));
  C := 999999989001.6;
  Writeln(Round(C));
  Readln;
end.
哪个输出

999999989000 999999989000 999999989001 999999989001 999999989002 999999989002 999999989000 999999989001 999999989001 999999989001 999999989002 999999989002
你把事情搞得太复杂了。您只需使用
Round

program Project1;
{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  C: Currency;

begin
  C := 999999989000.4;
  Writeln(Round(C));
  C := 999999989000.5;
  Writeln(Round(C));
  C := 999999989000.6;
  Writeln(Round(C));
  C := 999999989001.4;
  Writeln(Round(C));
  C := 999999989001.5;
  Writeln(Round(C));
  C := 999999989001.6;
  Writeln(Round(C));
  Readln;
end.
哪个输出

999999989000 999999989000 999999989001 999999989001 999999989002 999999989002 999999989000 999999989001 999999989001 999999989001 999999989002 999999989002
在我看来,你有两个选择:

  • 正如David Heffernan指出的那样,您使用
    Round
    函数
  • 如前所述,您可以使用
    SimpleRoundTo
    功能。
    SimpleRoundTo
    的优点是它接收
    Single
    Double
    Extended
    数据类型的参数,并且这些参数可以很好地对所述的数字进行四舍五入转换

  • 您不需要任何类型转换。您已经可以使用很多舍入函数。只需将所需数字四舍五入。

    在我看来,您有两个选择:

  • 正如David Heffernan指出的那样,您使用
    Round
    函数
  • 如前所述,您可以使用
    SimpleRoundTo
    功能。
    SimpleRoundTo
    的优点是它接收
    Single
    Double
    Extended
    数据类型的参数,并且这些参数可以很好地对所述的数字进行四舍五入转换

  • 您不需要任何类型转换。您已经可以使用很多舍入函数。只需将所需的数字四舍五入。

    这就是我实际使用的方法(如果这种方法有任何问题,我很想听听!)


    这就是我实际使用的方法(如果这种方法有任何问题,我很想听听!)


    看看约翰·赫伯斯特的取整程序。它们几乎提供您可能需要的任何类型的舍入,例如:

    drNone,    {No rounding.}
    drHalfEven,{Round to nearest or to even whole number. (a.k.a Bankers) }
    drHalfPos, {Round to nearest or toward positive.}
    drHalfNeg, {Round to nearest or toward negative.}
    drHalfDown,{Round to nearest or toward zero.}
    drHalfUp,  {Round to nearest or away from zero.}
    drRndNeg,  {Round toward negative.                    (a.k.a. Floor) }
    drRndPos,  {Round toward positive.                    (a.k.a. Ceil ) }
    drRndDown, {Round toward zero.                        (a.k.a. Trunc) }
    drRndUp);  {Round away from zero.}
    
    我现在不能给你一个链接,但是谷歌:十进制四舍五入约翰·赫伯斯特
    我认为他最近的舍入程序是小数舍入。他对浮点舍入的讨论(Embarcadero网站上的某个地方)是“必读内容”。

    看看John Herbster的舍入例程。它们提供了几乎任何您可能需要的舍入类型,例如:

    drNone,    {No rounding.}
    drHalfEven,{Round to nearest or to even whole number. (a.k.a Bankers) }
    drHalfPos, {Round to nearest or toward positive.}
    drHalfNeg, {Round to nearest or toward negative.}
    drHalfDown,{Round to nearest or toward zero.}
    drHalfUp,  {Round to nearest or away from zero.}
    drRndNeg,  {Round toward negative.                    (a.k.a. Floor) }
    drRndPos,  {Round toward positive.                    (a.k.a. Ceil ) }
    drRndDown, {Round toward zero.                        (a.k.a. Trunc) }
    drRndUp);  {Round away from zero.}
    
    我现在不能给你一个链接,但是谷歌:十进制四舍五入约翰·赫伯斯特
    我认为他最新的舍入程序是在DecimalRounding_JH1.pas中。他对浮点舍入的讨论(Embarcadero网站上的某个地方)是“必读”的.

    使用int64而不是integer?您建议的解决方案是错误的,不会起作用,因为您的问题是32位溢出。使用int64而不是integer?您建议的解决方案是错误的,不会起作用,因为您的问题是32位溢出。如果2.5到2,3.5到4,舍入不受银行家舍入的影响吗?(或者反过来说,我永远记不起来了)。0.5诀窍是在不干扰FPU设置的情况下解决这一问题的最简单方法?@Marjannema好吧,这就是
    Round
    的工作原理。如果你想要不同的东西,那么就使用不同的东西。好吧,这就是Round在标准FPU设置下的工作原理。这不是人们期望Round在具备基本数学知识的情况下工作,而是没有fi金融背景。当我发现这件事时,我当然很惊讶…@MarjanVenema不幸的是,高中的大多数人都被教授了从整数到无穷大的规则。这种舍入在科学或金融中没有使用,因为它引入了偏差,因为0.5总是向上舍入。FPU不默认为无穷大舍入的原因是谁也不在乎用它。舍入不是因为银行家的舍入而受到影响吗?2.5到2,3.5到4?(或者反过来,我永远记不起来)。0.5诀窍是在不干扰FPU设置的情况下解决这一问题的最简单方法?@Marjannema好吧,这就是
    Round
    的工作原理。如果你想要不同的东西,那么就使用不同的东西。好吧,这就是Round在标准FPU设置下的工作原理。这不是人们期望Round在具备基本数学知识的情况下工作,而是没有fi金融背景。当我发现这件事时,我当然很惊讶…@MarjanVenema不幸的是,高中的大多数人都被教授了从整数到无穷大的规则。这种舍入在科学或金融中没有使用,因为它引入了偏差,因为0.5总是向上舍入。FPU不默认为无穷大舍入的原因是没有人关心使用它。
    SimpleRoundTo(…,0)
    Round(…)
    有何不同?@DavidHeffernan在这种情况下,它没有。这就是为什么我说你的解决方案会给出相同的结果。但是,如果你想将一个数字四舍五入到一个给定的精度,它会产生不同。
    Round(…)
    SimpleRoundTo(…,0)的一个特例。
    @DavidHeffernan:它不使用银行取整。根据Bogdan链接到的文档,“此函数的结果取决于当前FPU取整模式…要在“银行模式”中取整,请使用System.Math.RoundTo。”SimpleRoundTo(…,0)是如何实现的不同于
    舍入(…)
    ?@DavidHeffernan在这种情况下,它不会。这就是为什么我说你的解决方案会给出相同的结果。但是,如果你想将一个数字舍入到给定的精度,它会产生不同。
    舍入(…)
    simplerundto(…,0)的一个特例
    @DavidHeffernan:它不使用银行取整。根据Bogdan链接到的文档,“此函数的结果取决于当前FPU取整模式…要在“银行模式”中取整,请使用System.Math.RoundTo。