- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
有几个关于浮点表示的问题发布到 SO。例如,十进制数 0.1 没有精确的二进制表示,因此使用 == 运算符将其与另一个 float 进行比较是危险的。我了解浮点表示法背后的原理。
我不明白的是,从数学的角度来看,为什么小数点右边的数字比左边的数字更“特殊”?
例如,数字 61.0 具有精确的二进制表示,因为任何数字的整数部分始终是精确的。但数字 6.10 并不准确。我所做的只是将小数点移动一位,突然间我从 Exactopia 变成了 Inexactville。从数学上讲,这两个数字之间应该没有本质区别——它们只是数字。
相比之下,如果我将小数点向另一个方向移动一位以生成数字 610,我仍然处于 Exactopia。我可以继续朝那个方向前进(6100、610000000、610000000000000),它们仍然非常准确、准确、准确。但是一旦小数点超过某个阈值,数字就不再准确了。
这是怎么回事?
编辑:澄清一下,我想远离有关行业标准表示的讨论,例如 IEEE,并坚持我认为是数学上“纯粹”的方式。在基数 10 中,位置值是:
... 1000 100 10 1 1/10 1/100 ...
在二进制中,它们是:
... 8 4 2 1 1/2 1/4 1/8 ...
这些数字也没有任意限制。位置向左和向右无限增加。
最佳答案
如果你有足够的空间,小数可以精确地表示——只是不是用 float 的二进制点数。如果您使用 float decimal 点类型(例如 .NET 中的 System.Decimal
),则可以精确表示许多无法用二进制 float 精确表示的值.
让我们换一种方式来看它 - 在您可能熟悉的基数 10 中,您无法准确表示 1/3。它是 0.3333333...(重复出现)。您不能将 0.1 表示为二进制 float 的原因完全相同。您可以准确表示 3、9 和 27,但不能表示 1/3、1/9 或 1/27。
问题是 3 是一个质数,它不是 10 的因数。当你想将一个数乘以 3 时,这不是问题:你总是可以乘以一个整数而不用遇到问题。但是,当您除以一个质数而不是您基数的一个因素时,您可能会遇到麻烦(如果您尝试除以 1,将会这样做按那个数字)。
虽然 0.1 通常用作无法用二进制 float 精确表示的精确十进制数的最简单示例,但可以说 0.2 是一个更简单的示例,因为它是 1/5 - 而 5 是导致两者之间出现问题的素数十进制和二进制。
一些 float 小数点类型具有固定大小,如 System.Decimal
其他如 java.math.BigDecimal
是“任意大” - 但它们会达到限制在某些时候,无论是系统内存还是数组的理论最大大小。但是,这是与该答案的主要答案完全不同的一点。即使您有真正任意多的位可供使用,您仍然无法在浮点二进制小数点表示法中准确地表示十进制 0.1。将其与另一种方式进行比较:给定任意数量的十进制数字,您可以精确地表示任何可以精确表示为浮点二进制小数点的数字。
关于math - 为什么十进制数不能用二进制精确表示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20121409/
感觉我在这里遗漏了一些明显的东西,所以提前道歉。无论如何,这是我尝试转换的一些数据a: acct_num year_prem prem exc 001 20
我正在尝试将表中的模式与用户话语 匹配。 string userUtterance = "I want identification number for number of customers";
当尝试在 Precise 上链接 gccgo 时,出现此链接错误: matt@matt-1005P:~/src/gopath/src/meme$ gccgo cmd/meme/main.go -o m
假设我有以下数据和命令: clc;clear; t = [0:0.1:1]; t_new = [0:0.01:1]; y = [1,2,1,3,2,2,4,5,6,1,0]; p = interp1(
假设我有以下数据和命令: clc;clear; t = [0:0.1:1]; t_new = [0:0.01:1]; y = [1,2,1,3,2,2,4,5,6,1,0]; p = interp1(
我总是想给精确匹配比只匹配前缀的分数更高的分数(例如,“ball”在与“ball*”匹配时应该比“ballistic”得到更高的分数)。 我当前(详细)的方法是在创建 PrefixQuery 时始终执
有什么解决方法可以让我在 Android 中使用 long 或 double 来寻找音频文件中的位置吗?目前 seekTo 只接受 ints 参数。我想更精确(比如在十分之一秒内) int resID
我的 replacingOccurrences 函数有问题。我有一个这样的字符串: let x = "john, johnny, johnney" 我需要做的只是删除“john” 所以我有这段代码:
我正在使用 BeautifulSoup 进行网页抓取。我有这段代码来提取 a 标签的值,但它似乎不起作用。显示错误: AttributeError: 'int' object has no attri
我要在带有标记顶点和标记有向边的图上寻找一种不精确的图匹配算法。我的任务是检测两个图表的变化以将它们显示给开发人员(想想颠覆差异)。我已经实现了基于禁忌搜索 ( this ) 的优化算法,但我无法让该
我有两个网站: example.com 和 yyy.com 他们都有类似的网络应用程序,但在不同的服务器上。我想让 Apache 将所有路径请求重定向到 example.com 与 完全相同的方式yy
因此,我尝试合并两个公司信息数据库(从现在起表 A 和表 B),其中最常见(且可靠)的单一引用点是网站 URL。表 A 已更新,表 B 待更新。 我已经从表 A 中提取了 URL,并使用 PHP 清理
我正在 http://classicorthodoxbible.com/new.html 上制作效果主要描述中的 Angular 色,包裹在自己的跨度中,从他们通常的休息地点移动到随机位置,然后通过指
我目前正在使用我的 Raspberry Pi 及其内置 UART 输入编写 MIDI 合成器。 在某个时间点,为了启用 MIDI 输入的实时回放,我必须设置一种环形缓冲区以与 OpenAL 一起使用,
在 C 中,当设置了一个 float 时, int main(int argc, char *argv[]) { float temp = 98.6f; printf("%f\n",
实现 MP3 无间隙循环的最佳可能性是什么?目前我正在使用 AVAudioPlayer 并将 .numberOfLoops() 属性设置为 -1 但可以听到,轨道重新启动。情况并非如此,例如使用 Tr
我想创建不一定是“正确”矩阵的“类矩阵”对象。但是,确切地说,“类矩阵”是什么意思? 示例 1 > image(1:9) Error in image.default(1:9) : argument
给定一个像这样的 XML 文档: john &title; 我想解析上面的 XML 文档并生成其所有实体已解析的副本。因此,给定上述 XMl 文档,解析器应输出: john
需要说明的是,这种方法不是我要找的: 事实上,此方法会调整 ImageField 的大小。我想将 Image 对象的大小调整为特定且精确的无比例分辨率。有什么办法吗? --编辑-- 对我来说,Ima
我正在尝试使用 TF2.0 eager 模式执行精确的 GP 回归,基于来自 https://colab.research.google.com/github/tensorflow/probabili
我是一名优秀的程序员,十分优秀!