- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
编译器选择的“小”的演示者
作为 Ada 中定点类型的新手,听到 'Small 的默认值是 2 的幂,小于或等于指定的 delta 时,我感到很惊讶。这是介绍问题的简短片段:
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
type foo is delta 0.1 range 0.0..1.0;
x : foo := foo'delta;
begin
Put (x'Image);
while true loop
x := x + foo'delta;
Put (x'Image);
end loop;
end Main;
输出显示 'Small 确实是小于 0.1 的 2 的最大幂,因为某些打印值出现了两次:
0.1 0.1 0.2 0.3 0.3 0.4 0.4 0.5 0.6 0.6 0.7 0.8 0.8 0.9 0.9 1.0
raised CONSTRAINT_ERROR : main.adb:9 range check failed
解决方案:将它们指定为相同的值
real_delta : constant := 0.1;
type foo is delta real_delta range 0.0..1.0
with Small => real_delta;
题;将两者指定为不同的值是否有用?
type foo is delta 0.1 range 0.0..1.0
with Small => 0.07;
x : foo := 0.4 + 0.4; -- equals 0.7 rather than 0.8
这似乎只会让后来遇到这个问题的可怜的读者感到困惑。以下示例取自 John Barnes 的 Programming in Ada 2012,第 434 页的第 17.5 节。他没有解释为什么 delta 是一个更大的值,而不是实际使用的“小”的倍数。
π : constant := Ada.numerics.π;
type angle is delta 0.1 range -4*π .. 4 *π;
for Angle'Small use π * 2.0**(-13);
我看到的唯一区别是“图像现在只打印一位数的精度。这是唯一的区别吗?
for foo'Small use foo'Delta
?
type foo is delta 0.1 range 0.0..1.0;
for foo'Small use foo'Delta;
但 GNAT 提示 foo 在声明后立即被卡住:
main.adb:6:04: representation item appears too late
这在某些版本的 Ada 中有所改变吗?它应该是有效的 Ada2012 吗?
最佳答案
免责声明 : 所以定点算术是一个比较特殊的话题。这就是我对这个主题的理解,但我必须在这里发出警告:我在下面写的内容可能不正确。所以对于所有阅读它的人:如果我错了,请纠正我。
在 Ada 中,真实类型由其准确性定义。这与通过实现(即硬件表示)定义真实类型的大多数其他语言相反。在实际类型的定义中选择使用准确性属性而不是表示方面符合语言哲学:准确性作为一个概念,与正确性密切相关;语言的目标。根据准确性定义真实类型也更自然,因为您让编译器根据您对准确性的要求选择最佳类型(在计算机上,无论如何,所有值都是近似值,您必须一次性处理该事实-方式或其他)。Delta
属性定义了对与基础定点类型相关的绝对误差界限(准确度)的要求(另见 Ada 83 Rationale, section 5.1.3)。优点有两方面:
Update 24-10-2020: These former paragraphs should be read in the context of the original language specification, Ada 83. Moreover the Ada 83 language had a second important objective that seemed to have influenced the choice for defining numeric real types using accuracy: the separation principle. See, the Ada 83 Rationale, chapter 15 for a clear statement on what this meant. When Ada 95 was developed, however, the separation between logical type properties (like accuracy) and machine representation was (at least for fixed-point types) reviewed and found to be not as useful in practice as what was hoped for (see the Ada 95 Rationale, section G.4.2). Hence, as of Ada 95, the role of the
Delta
attribute has been diminished and theSmall
attribute has been used instead in the formulation of how fixed-point types and operations should work (see, for example, RM G.2.3).
type Fix is delta 0.07 range 0.0 .. 10.0; -- 0.07 is just a random value here
换句话说,当给定的“真”值被强制转换为类型
Fix
时,那么它将获得 +/- 0.07 的不确定性。因此,三个命名常量
X
,
Y
和
Z
在下面的程序中,当转换为类型
Fix
时, 变得:
X : constant := 5.6; -- Becomes 5.6 +/- 0.07 when casted to type Fix.
Y : constant := 0.3; -- Becomes 0.3 +/- 0.07 when casted to type Fix.
Z : constant := 2.5; -- Becomes 2.5 +/- 0.07 when casted to type Fix.
鉴于这些不确定性,我们可以计算一些算术运算序列的结果的不确定性(另请参阅
this 关于 SO 的优秀答案)。这实际上在程序中得到了演示。
Update 24-10-2020: In retrospect, this doesn't seem to be correct and there are complications. The computations of uncertainty in the program do not take into account the intermediate and final casting (quantization) of numbers that may occur during the computation and final assignment. Hence, the computed uncertainties are not correct and too optimistic (i.e. they should be larger). I will not delete the example program though as it does provide an intuition for the original intend of the
Delta
attribute.
Long_Float
(
Flt
) 和自定义定点类型
Fix
.使用
Long_Float
的计算结果当然,也是一个近似值,但为了演示起见,我们可以假设它是精确的。然而,定点计算的结果具有(非常)有限的精度,因为我们为类型
Fix
指定了相当大的误差界限。 .另一方面,定点值需要更少的空间(这里:每个值只有 8 位)并且算术运算不需要专门的浮点硬件。
Small
的事实属性只是为了让程序员可以控制定点类型定义的集合中可用的型号。总是制作
Small
可能很诱人表示方面等于
Delta
属性,但使它们相等(通常)不会改变在使用定点数和算术运算时需要执行一些数值(错误)分析的要求。
Update 24-10-2020: This statement is only partly correct I think. The
Small
attribute does allow programmers to control the model numbers (i.e. number that can be represented exactly by the data type), but it's not just that. As of Ada 95, theSmall
attribute plays a major role in how fixed-point arithmetic is supposed to work (RM G.2.3) and, moreover, most documentation on fixed-point arithmetic and software to analyze fixed-point algorithms (see, for example here) assume that actual representation of the type in hardware is known; their treatment of the subject does not depart from an absolute error bound, but always depart from the representation of a fixed-point value.
Update 24-10-2020: Also this statement requires a remark: not requiring floating-point operations for executing fixed-point operations in Ada depends on a context. Fixed-point operations, in particular multiplication and division, can be done using only integer operations if the type of the operands and result of the operation have particular values for
Small
. It's too much detail to put here, but some interesting information can actually be found in the well documented source code of GNAT itself, see, for example,exp_fixd.adb
.
Update 24-10-2020: So in conclusion, given the changes in Ada 95 and given the current state-of-art in tools for performing fixed-point analysis, there seems no strong argument to choose the values for
Delta
andSmall
differently. TheDelta
attribute still represents the absolute error bound, but it's value is not as useful as thought originally. It's only major use seems, as you already mentioned, be in the I/O of fixed-point data-types (RM 3.5.10 (5) andAda.Text_IO.Fixed_IO
).
pragma Warnings (Off, "static fixed-point value is not a multiple of Small");
pragma Warnings (Off, "high bound adjusted down by delta (RM 3.5.9(13))");
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
type Flt is new Long_Float;
type Fix is delta 0.07 range 0.0 .. 10.0;
---------
-- Put --
---------
procedure Put (Nominal, Uncertainty : Flt; Result : Fix) is
package Fix_IO is new Fixed_IO (Fix);
use Fix_IO;
package Flt_IO is new Float_IO (Flt);
use Flt_IO;
begin
Put (" Result will be within : ");
Put (Nominal, Fore => 2, Aft => 4, Exp => 0);
Put (" +/-");
Put (Uncertainty, Fore => 2, Aft => 4, Exp => 0);
New_Line;
Put (" Actual fixed-point result : ");
Put (Result, Fore => 2);
New_Line (2);
end Put;
X : constant := 5.6;
Y : constant := 0.3;
Z : constant := 2.5;
D : constant Flt := Fix'Delta;
begin
Put_Line ("Size of fixed-point type : " & Fix'Size'Image);
Put_Line ("Small of fixed-point type : " & Fix'Small'Image);
New_Line;
-- Update 24-10-2020: Uncertainty computation is too optimistic. It omits
-- the effect of quantization in intermediate and final
-- variable assignments.
Put_Line ("X + Y = ");
Put (Nominal => Flt (X) + Flt (Y),
Uncertainty => D + D,
Result => Fix (X) + Fix (Y));
Put_Line ("X * Y = ");
Put (Nominal => Flt (X) * Flt (Y),
Uncertainty => (D / X + D / Y) * X * Y,
Result => Fix (X) * Fix (Y));
Put_Line ("X * Y + Z = ");
Put (Nominal => Flt (X) * Flt (Y) + Flt (Z),
Uncertainty => (D / X + D / Y) * X * Y + D,
Result => Fix (X) * Fix (Y) + Fix (Z));
end Main;
输出
Size of fixed-point type : 8
Small of fixed-point type : 6.25000000000000000E-02
X + Y =
Result will be within : 5.9000 +/- 0.1400
Actual fixed-point result : 5.81
X * Y =
Result will be within : 1.6800 +/- 0.4130
Actual fixed-point result : 1.38
X * Y + Z =
Result will be within : 4.1800 +/- 0.4830
Actual fixed-point result : 3.88
关于ada - 单独指定 'Small and ' Delta 是否有意义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64479997/
我有一个 if 语句,如下所示 if (not(fullpath.lower().endswith(".pdf")) or not (fullpath.lower().endswith(tup
然而,在 PHP 中,可以: only appears if $foo is true. only appears if $foo is false. 在 Javascript 中,能否在一个脚
XML有很多好处。它既是机器可读的,也是人类可读的,它具有标准化的格式,并且用途广泛。 它也有一些缺点。它是冗长的,不是传输大量数据的非常有效的方法。 XML最有用的方面之一是模式语言。使用模式,您可
由于长期使用 SQL2000,我并没有真正深入了解公用表表达式。 我给出的答案here (#4025380)和 here (#4018793)违背了潮流,因为他们没有使用 CTE。 我很欣赏它们对于递
我有一个应用程序: void deleteObj(id){ MyObj obj = getObjById(id); if (obj == null) { throw n
我的代码如下。可能我以类似的方式多次使用它,即简单地说,我正在以这种方式管理 session 和事务: List users= null; try{ sess
在开发J2EE Web应用程序时,我通常会按以下方式组织我的包结构 com.jameselsey.. 控制器-控制器/操作转到此处 服务-事务服务类,由控制器调用 域-应用程序使用的我的域类/对象 D
这更多是出于好奇而不是任何重要问题,但我只是想知道 memmove 中的以下片段文档: Copying takes place as if an intermediate buffer were us
路径压缩涉及将根指定为路径上每个节点的新父节点——这可能会降低根的等级,并可能降低路径上所有节点的等级。有办法解决这个问题吗?有必要处理这个吗?或者,也许可以将等级视为树高的上限而不是确切的高度? 谢
我有两个类,A 和 B。A 是 B 的父类,我有一个函数接收指向 A 类型类的指针,检查它是否也是 B 类型,如果是将调用另一个函数,该函数接受一个指向类型 B 的类的指针。当函数调用另一个函数时,我
有没有办法让 valgrind 使用多个处理器? 我正在使用 valgrind 的 callgrind 进行一些瓶颈分析,并注意到我的应用程序中的资源使用行为与在 valgrind/callgrind
假设我们要使用 ReaderT [(a,b)]超过 Maybe monad,然后我们想在列表中进行查找。 现在,一个简单且不常见的方法是: 第一种可能性 find a = ReaderT (looku
我的代码似乎有问题。我需要说的是: if ( $('html').attr('lang').val() == 'fr-FR' ) { // do this } else { // do
根据this文章(2018 年 4 月)AKS 在可用性集中运行时能够跨故障域智能放置 Pod,但尚不考虑更新域。很快就会使用更新域将 Pod 放入 AKS 中吗? 最佳答案 当您设置集群时,它已经自
course | section | type comart2 : bsit201 : lec comart2 :
我正在开发自己的 SDK,而这又依赖于某些第 3 方 SDK。例如 - OkHttp。 我应该将 OkHttp 添加到我的 build.gradle 中,还是让我的 SDK 用户包含它?在这种情况下,
随着 Rust 越来越充实,我对它的兴趣开始激起。我喜欢它支持代数数据类型,尤其是那些匹配的事实,但是对其他功能习语有什么想法吗? 例如标准库中是否有标准过滤器/映射/归约函数的集合,更重要的是,您能
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 9 年前。 Improve
我一直在研究 PHP 中的对象。我见过的所有示例甚至在它们自己的对象上都使用了对象构造函数。 PHP 会强制您这样做吗?如果是,为什么? 例如: firstname = $firstname;
...比关联数组? 关联数组会占用更多内存吗? $arr = array(1, 1, 1); $arr[10] = 1; $arr[] = 1; // <- index is 11; does the
我是一名优秀的程序员,十分优秀!