Language agnostic 可施工点的坐标能否准确表示?

Language agnostic 可施工点的坐标能否准确表示?,language-agnostic,math,geometry,numbers,Language Agnostic,Math,Geometry,Numbers,我想写一个程序,让用户像用直尺和指南针一样画点、线和圆。然后我想回答这个问题,“这三个点是共线的吗?”为了正确回答,我需要在计算点时避免舍入误差 这可能吗?如何表示内存中的点 (我查看了一些不寻常的数字库,但我没有发现任何声称提供精确算术和保证终止的精确比较的东西。)如果网格轴是整数值,那么答案是相当直接的,这些点要么是完全共线的,要么不是 然而,通常情况下,我们使用实数(也就是浮点数),然后在屏幕上绘制整数空间中的舍入值。在这种情况下,您别无选择,只能选择公差并使用它来确定共线性。保持较小,用

我想写一个程序,让用户像用直尺和指南针一样画点、线和圆。然后我想回答这个问题,“这三个点是共线的吗?”为了正确回答,我需要在计算点时避免舍入误差

这可能吗?如何表示内存中的点


(我查看了一些不寻常的数字库,但我没有发现任何声称提供精确算术和保证终止的精确比较的东西。)

如果网格轴是整数值,那么答案是相当直接的,这些点要么是完全共线的,要么不是


然而,通常情况下,我们使用实数(也就是浮点数),然后在屏幕上绘制整数空间中的舍入值。在这种情况下,您别无选择,只能选择公差并使用它来确定共线性。保持较小,用户将永远不会知道差异。

我认为唯一可行的方法是使用符号表示, 与试图直接表示坐标值相反——因此 为了避免将像sqrt(2)这样的值强制转换为某种数字格式。你会 处理非有限二进制表示的无理数,
十进制或任何其他位置符号。

我建议不要尝试使其完全精确

第一个原因是你在这里要问的,舍入误差和所有浮点计算带来的东西

第二个问题是,当鼠标和屏幕处理整数时,必须对输入进行四舍五入。所以,最初所有的用户输入都是整数,而您的输出都是整数


旁边,从可用性的角度来看,它更容易点击另一个点的邻域(例如在一行中),并且界面认为你在点本身点击。

在<>强> Jim Lewis < /St>的回答略微扩展,如果要对可通过精确算术从整数构造的点进行运算,则需要能够对以下形式的表示进行运算:

a + b sqrt(c)
其中a、b和c是有理数,或者是上述形式的表示。关于什么样的点是可构造的,有一篇相当不错的文章


用这种表示法回答完全相等的问题(建立共线所必需的)是一个相当棘手的问题。

如果你试图比较点的坐标,那么你就有问题了。暂时撇开共线性不谈,看看两点是否相同如何

假设一个给定了坐标,另一个是从其他坐标开始的罗盘直尺构造,你想要确定它们是否是同一点。无论哪种方法都是欧几里德几何的一个定理,它不是你可以测量的东西。你可以通过发现它们坐标上的一些差异来证明它们是不同的(例如,计算每个坐标的小数点,直到你遇到差异为止)。但一般来说,用近似方法无法证明它们是相同的。计算
1/sqrt(2)
sqrt(2)/2
的一些展开式的任意小数位数,你可以证明它们非常接近,但你永远无法证明它们相等。这需要代数(或几何)


同样,为了证明三点是共线的,你需要定理证明软件。用点的结构表示点A、B、C,并试图证明定理“A、B、C是共线的”。这是非常困难的-您的程序将证明一些定理,但不会证明其他定理。更简单的方法是要求用户证明它们是共线的,然后验证(或反驳)该证明,但这可能不是你想要的。

实际上,你似乎在问,“计算机使用的普通数学(整型或浮点型)能完美地表示实数而没有舍入错误吗?”当然,还有,答案是“不”。如果你想要理论上的正确性,那么你将被困在更难的问题上,即符号操作和编码几何推理的等价物。(简而言之,我同意上面Steve Jessop的观点。)

一般来说,可构造点可能具有任意复杂的符号形式,因此必须使用符号表示来精确地处理它们。正如Stephen Canon在上面提到的,你们经常需要a+b*sqrt(c)形式的数字,其中a和b是有理数,c是整数。这种形式的所有数字在算术运算下形成一个闭合集。我已经写了(见rational_radical1.h)来处理这些数字,如果这就是您所需要的

也可以构造任意数量的根的有理倍数项的和的数。当处理多个单半径D时,数字在乘法和除法下不再闭合,因此需要将它们存储为可变长度有理系数数组。然后,操作的时间复杂度将是项数的二次方

更进一步,您可以构造任意给定数字的平方根,因此您可能具有嵌套的平方根。这里,表示必须是树状结构,以处理根层次结构。虽然很难实现,但原则上没有任何东西阻止您使用这些表示。我不确定可以构造哪些额外的数字,但超过某一点,您的符号表示将足够表达,可以处理非常大的数字类

附录

找到了这个。

我强烈推荐,这是一个很好的基本指南

基本上,您需要能够使用-n进行计算