【问题标题】:Delphi - comparison of two "Real" number variablesDelphi - 两个“实”数变量的比较
【发布时间】:2016-03-19 14:52:49
【问题描述】:

我在比较“Real”类型的两个变量时遇到问题。一个是数学运算的结果,存储在数据集中,第二个是表单中编辑字段的值,由 StrToFloat 转换并存储到“Real”变量中。问题是这样的:

如您所见,程序试图告诉我,121,97 不等于 121,97...我已阅读 this topic,我不完全确定这是同一个问题。如果是,那么存储在变量中的两个数字不会是完全相同的最接近的可表示数字,对于 121.97,它是 121.96999 99999 99998 86313 16227 83839 70260 62011 71875 吗?

现在假设它们没有存储为相同的最接近的可表示数字。我如何找到它们的存储方式?当我查看“CPU”调试窗口时,我完全迷失了方向。我看到了地址,这些值应该在哪里,但没有任何类似于二进制、十六进制或实际数字的任何表示的东西......我承认,高级调试对我来说是未知的世界......

编辑: 这两个值确实略有不同。

好的,我不需要了解所有内容。虽然我不是在处理金钱,但最多会有3位小数,所以“货币”是出路

顺便说一句:计算是:

DATA[i].Meta.UnUsedAmount := DATA[i].AMOUNT - ObjQuery.FieldByName('USED').AsFloat;

在这种情况下,它是 3695 - 3573.03

【问题讨论】:

  • 参见 JIRA RSP-13792。您可能想要调用comparevalue 函数。
  • @Magoo 那份报告是假的。编译器行为正确。
  • StrToFloat 应该如你所说。但是其他值呢?它是如何计算的。我认为您应该关注我们看不到的实际问题。
  • 在inspector/watch窗口中将变量可视化为二进制,你会发现它不一样...
  • 使用currency 表示金额。你所有的问题都会迎刃而解。

标签: delphi floating-point


【解决方案1】:

由于未知原因,您无法在观察列表中将浮点值(单/双或 real48)视为十六进制。

但是,您仍然可以通过将其视为内存转储来查看十六进制表示。
就是这样: 将变量添加到观察列表。
右键单击手表 -> 编辑手表...
查看为memory dump

现在您可以在调试器中比较这两个值。

切勿将浮点数用于货币金额
您当然知道不应该使用浮点数来数钱。
舍入时您会遇到各种麻烦,并且比较也不会按照您想要的方式进行。
如果您想使用金钱,请改用currency 类型。它没有这些问题,支持 4 位小数,并且可以使用 = 运算符进行比较,没有舍入问题。

在您的数据库中,您使用moneycurrency 数据类型。

【讨论】:

  • 是的,但不是在你用钱工作的时候。更新了答案。除非您确切知道自己在做什么,否则与浮点数进行相等比较是灾难的根源
  • 谢谢!是否可以简要描述我在内存转储中看到的内容?很抱歉,但我还没有成功地弄清楚......我的意思是 - 121.97 的十六进制表示是 0x42f3f0a4 ...
  • double 的表示是正确的,您可能在谈论 single 或 -shudder-real48。这些值的二进制表示是不同的。
  • 啊,好的,这超出了我的想象......但是非常感谢您的帮助
  • @DavidHeffernan,amount,是的,我指的是货币。在我的母语中,货币金额和其他金额的词是不同的。我一直忘记英语的数量也可以用来表示其他无聊的旧数量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-04
  • 1970-01-01
相关资源
最近更新 更多