【问题标题】:Ada 2012 - replace Fixed_Decimal_Type'Round() with customised version?Ada 2012 - 用定制版本替换 Fixed_Decimal_Type'Round()?
【发布时间】:2019-10-16 18:28:37
【问题描述】:

最近我在为自定义记录类型提供自己的替换'Write () 过程时取得了巨大的成功,例如...

   type Pixel_Format is
      record
         --  blah blah
      end record;

   procedure Pixel_Format_Write (
     Stream : not null access Root_Stream_Type'Class;
     Item : in Pixel_Format);

   for Pixel_Format'Write use Pixel_Format_Write;

在写入网络流时,我使用它来将某些记录成员从小端转换为大端。效果很好。

出于同样的想法,我想知道是否可以替换十进制定点类型的'Round () 函数,所以我尝试了一个快速而肮脏的测试......

   --  This is a "Decimal Fixed Point" type
   type Money_Dec_Type is delta 0.001 digits 14;

   --  ...

   function Money_CustomRound(X : in Money_Dec_Type)
     return Money_Dec_Type'Base;

   for Money_Dec_Type'Round use Money_CustomRound; -- COMPILER COMPLAINS HERE

   --  ...

   function Money_CustomRound(X : in Money_Dec_Type)
     return Money_Dec_Type'Base is

     begin
        return 0.001;
   end Money_CustomRound;

唉,GNAT 觉得这很冒犯:

attribute "Round" cannot be set with definition clause

问题:

我在尝试不可能的事情吗?或者有没有办法改变默认的'Round 属性,就像改变'Write 一样?

问题的背景:

我有一组大约 15 种不同的四舍五入货币值的方法,这些方法从一个项目到另一个项目(有时在同一个项目中!)。示例包括:

  • 从零开始取整(似乎是 Ada 的默认值)
  • 向零取整
  • 统计(需要全局管理的可重入类型)
  • 轮到偶数或赔率
  • 向 +INF / -INF 舍入
  • ...

通过使用在通用包级别定义的某些舍入方法,能够使这种功能对程序员透明,这将是一个强大的工具。

我另一个肩膀上的天使暗示我在要求一些完全疯狂的东西。

我想知道这是因为文档(ALRM 和“Barnes 2012”)都给出了默认过程的功能规范。如果一个人不能用自己的设计替换它,他们为什么要这样做?

【问题讨论】:

  • 无论如何您都必须编写代码,那么重新定义属性而不是仅仅拥有一个函数Round 有什么好处呢? ...实际上最终会得到更短的代码
  • @SimonWright,使用旧默认行为的现有函数不必针对新要求进行修改。
  • 在进行移植/重构时,我经常遇到这种对查找替换代码的“恐惧”。我经常认为这是管理层对开发人员和软件演变缺乏信心的象征。即使我你可以重新定义 le ‘Round,你也必须评估(测试)它对所有用户的影响。无论如何都会进行影响分析和测试。为什么然后让«打开+编辑»n个文件成为一个可怕的事件?软件会随着时间的推移而变化,无论人们多么不希望它发生变化。
  • @LoneWanderer,是的,你是对的。我希望这也不是一个症结所在。我也希望我有能力对此做任何事情:)
  • @LoneWanderer 并不总是害怕,还有一个简单的便利因素。如果它“刚刚发生”,那么您就没有做额外的工作。

标签: rounding ada fixed-point


【解决方案1】:

不,您不能重新定义 Round 属性。只能查询属性(请参阅RM K.2)。只有方面可以(重新)使用方面规范定义(请参阅RM K.1;有一些例外情况适用)。 RM 给出了属性背后的功能规范,以向读者阐明签名。

【讨论】:

  • 四个属性:读/写和输入/输出实际上可以重新定义。然而,这些是唯一的例外。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-05
  • 1970-01-01
  • 1970-01-01
  • 2015-01-19
  • 2018-02-20
相关资源
最近更新 更多