有没有“正常”的情况? Mathematica 中的 EqualQ 函数?
在 Equal
的文档页面上,我们读到
机器的大概数字 考虑精度或更高 如果他们至多有差异,则相等 最后七个二进制数字(大约 最后两位小数)。
以下是示例(32 位系统;对于 64 位系统,请在中间添加一些零):
In[1]:= 1.0000000000000021 == 1.0000000000000022
1.0000000000000021 === 1.0000000000000022
Out[1]= True
Out[2]= True
我想知道 Mathematica 中是否存在 Equal
函数的“正常”模拟 em> 不会删除最后 7 个二进制数字?
On the documentation page for Equal
we read that
Approximate numbers with machine
precision or higher are considered
equal if they differ in at most their
last seven binary digits (roughly
their last two decimal digits).
Here are examples (32 bit system; for 64 bit system add some more zeros in the middle):
In[1]:= 1.0000000000000021 == 1.0000000000000022
1.0000000000000021 === 1.0000000000000022
Out[1]= True
Out[2]= True
I'm wondering is there a "normal" analog of the Equal
function in Mathematica that does not drop last 7 binary digits?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
感谢最近在官方新闻组上帖子 Oleksandr Rasputinov,现在我学会了两个未记录的函数,它们控制
Equal
和SameQ
的容差:$EqualTolerance
和$SameQTolerance.在 Mathematica 版本 5 及更早版本中,这些函数存在于
Experimental`
上下文中,并且有详细记录:$EqualTolerance,$SameQTolerance。从版本 6 开始,它们移至Internal`
上下文 变得无证,但仍然可以工作,甚至有内置的诊断消息,当有人试图为它们分配非法值时会出现这些消息:引用 Oleksandr Rasputinov:
这样,将
Internal`$EqualTolerance
设置为零将强制Equal
仅当所有二进制数字都相同时才认为数字相等(不考虑超出>Precision
数字):请注意以下情况:
在这种情况下,两个数字都有
MachinePrecision
,实际上是(
53*Log[10, 2]
)。有了这样的精度,这些数字在所有二进制数字中都是相同的:将精度增加到 16 使它们成为不同的任意精度数字:
但不幸的是
Equal
仍然无法区分它们:有无数这样的情况:
有趣的是,有时
RealDigits
返回相同的数字,而Order
显示表达式的内部表示不相同:但似乎新发生了相反的情况:
Thanks to recent post on the official newsgroup by Oleksandr Rasputinov, now I have learned two undocumented functions which control the tolerance of
Equal
andSameQ
:$EqualTolerance
and$SameQTolerance
. In Mathematica version 5 and earlier these functions live in theExperimental`
context and are well documented: $EqualTolerance, $SameQTolerance. Starting from version 6, they are moved to theInternal`
context and become undocumented but still work and even have built-in diagnostic messages which appear when one try to assign them illegal values:Citing Oleksandr Rasputinov:
In this way, setting
Internal`$EqualTolerance
to zero will forceEqual
to consider numbers equal only when they are identical in all binary digits (not considering out-of-Precision
digits):Note the following case:
In this case both numbers have
MachinePrecision
which effectively is(
53*Log[10, 2]
). With such precision these numbers are identical in all binary digits:Increasing precision to 16 makes them different arbitrary-precision numbers:
But unfortunately
Equal
still fails to distinguish them:There is an infinite number of such cases:
Interestingly, sometimes
RealDigits
returns identical digits whileOrder
shows that internal representations of expressions are not identical:But it seems that opposite situation newer happens:
试试这个:
基数 2 的选择对于确保比较内部表示至关重要。
Try this:
The choice of base 2 is crucial to ensure that you are comparing the internal representations.
此测试两个对象是否相同,因为 1.0000000000000021 和 1.000000000000002100 的精度不同,因此它们不会被视为相同。
This tests if two object are identical, since 1.0000000000000021 and 1.000000000000002100 differs in precision they won't be considered as identical.
我不知道已经定义的运算符。但您可以定义例如:
例如:
编辑
如果您想概括任意数量的数字,您可以这样做:
这样您评论中的反例也有效。
哈!
I'm not aware of an already defined operator. But you may define for example:
Such as:
Edit
If you want to generalize for an arbitrary number of digits, you can do for example:
So that your counterexample in your comment also works.
HTH!
我提出了一种使用
RealDigits
来比较数字的实际数字的策略。唯一棘手的一点是去掉尾随零。I propose a strategy that uses
RealDigits
to compare the actual digits of the numbers. The only tricky bit is stripping out trailing zeroes.我认为你真的必须明确你想要什么......没有办法比较近似的实数来满足每个人在每种情况下的需求。
无论如何,这里还有几个选项:
随着两个数字的精度越来越高,如果您将
tol
设置得足够高,那么它们总是可以区分的。请注意,减法是以两个数字中最低的精度进行的。 的操作来使其以较高数字的精度发生(这似乎有点毫无意义)
您可以通过执行诸如使用最小精度之类
I think that you really have to specify what you want... there's no way to compare approximate real numbers that will satisfy everyone in every situation.
Anyway, here's a couple more options:
As the precision of both numbers gets higher, then they can always be distinguished if you set
tol
high enough.Note that the subtraction is done at the precision of the lowest of the two numbers. You could make it happen at the precision of the higher number (which seems a bit pointless) by doing something like
maybe using the minimum precision makes more sense
定义此类函数的另一种方法是使用 SetPrecision:
这似乎适用于所有情况,但我仍然想知道是否有内置函数。使用高级函数来完成如此原始的任务是很丑陋的......
One other way to define such function is by using SetPrecision:
This seems to work in the all cases but I'm still wondering is there a built-in function. It is ugly to use high-level functions for such a primitive task...