我一直在阅读有关浮点数,看看它们是什么,以及一个网站说过这个。
物理学家需要在同一计算中同时使用光速(约300000000)和牛顿的引力常数(约0.0000000000667)。 为了满足工程师和芯片设计人员的需要,数字格式必须以非常不同的幅度提供数字的准确性。但是,只需要相对准确性。为了满足物理学家的要求,必须能够进行涉及不同数量的数字的计算。
基本上,具有固定数量的整数和小数位是没有用的 - 并且解决方案是具有浮点的格式。
我对第二段有两个问题。
floor((0.1+0.7)*10)
(由于舍入误差* [source]计算为7而不是8),它如何适用于从非常高到极低的数字(就像上面关于物理学家的引文一样),考虑到它无法用前面例子中0.1 - 8
的数字来计算正确的答案。为什么物理学家会使用浮点计算,为什么不像其他人一样使用精确小数?有人告诉我不要用它们来赚钱,所以为什么要把它们用于科学呢
此外,如果计算floor((0.1+0.7)*10)
或0.1 + 0.2
(等于0.30000000000000004)是如此困难,但不是整数,为什么计算机不能计算总和没有小数点((01 + 07) * 10)
或01 + 02
,然后将其放回到答案中(从南方添加小数点1位数)?我知道一个比我年轻的17岁的孩子正在编写一个编译成javascript的编程语言。为什么程序员不能想到从总和中删除小数点(如果算小数或负数很难计算),然后将小数点放回到最终答案中?由于他们的主要错误,0.15 + 0.15
和0.1 + 0.2
如果与==
或>=
相互比较,则可以返回false。这绝对是疯狂的!
* 7.9999999999999991118 ....
答案 0 :(得分:6)
建议将基数10用于财务计算,因为财务计算符合他们自己的标准(example),这些标准根据基数10计算定义“正确”结果。使用base-2浮点计算来模拟正确的计算是很困难的,因为它不能自然地与财务标准的基础10语言相匹配。
物理学没有基础10人类标准服从(物理学没有10个手指),所以任何基础都和其他基础一样好。你指出了一个基础2变坏的例子,floor((0.1+0.7)*10)
,但同样容易使基数10变坏:floor(10 / 3 * 3) = 9
以十进制计算任何精度。
事实上,涉及floor
的任何计算的问题是floor
不稳定:参数中的小错误可能导致结果中出现大的错误。如果你避免不稳定的计算,那么一个基础应该和你的实现一样好。当用逻辑电路实现时,二进制有几个优点。
0.15 + 0.15和0.1 + 0.2
在0和1之间存在无限多的有理数。其中,你清楚地期望0.15,0.1和0.2并且它们的总和被精确地表达。如果您有这些期望,那么基数10适合您。物理学家没有任何理由支持这些数字:他们使用π, G ,其他常数我不知道。即使其中一个常数恰好是0.1,物理学家也无法准确地表示它们的常数。物理学家对于在0和1之间的所有其他有理数上具有短十进制扩展的数字没有特别的偏好,其绝大多数都不会通过一个微不足道的计数参数完全表达。
答案 1 :(得分:3)
在处理数字(和日期!)时,为每项工作使用正确的工具非常重要。你必须至少考虑:
在基本的财务计算中,你处理可以计算的事情:在最基本的层面上,你处理整个便士。这在进行高级计算时是不同的,例如,在处理具有复合权益的投资或计算具有概率的保险时。
使用分数时,您会遇到以下问题:使用数字的系统无法代表只有finit数字位数的大多数分数。二元系统只能表示可以由1 / 2,1 / 4,1 / 8等组成的分数(例如,可以表示3/8 = 1/4 + 1/8,而1/10不能表示)。十进制系统稍好一点。它可以比二进制系统表达更多的分数。它仍然在与1/3之类的简单分数中挣扎。
如果要精确表达分数,则必须将它们表示为分数。这意味着你必须分别计算分子和分母。只有这样,您才能获得准确而稳定的结果但计算将是狗慢。实际上,像Mathematica和Maple这样的计算机代数系统恰好提供了这种模式。
当问题域得到充分理解时,可以通过使用某些快捷方式获得很快的速度。一个捷径是抛弃准确性并使用近似结果。执行此操作时,以保持所需数值稳定性的方式对部分计算进行排序非常重要。一个非常简单的示例:1/sqrt(x)
不如sqrt(x)/x
准确。进行这种优化需要严格的数学分析。否则,结果不仅不准确,而且完全错误。
物理学家可以使用不精确的浮点运算,当她分析对准确性的影响时,以及何时以保持所需数值稳定性的方式对算法进行编码。在进行高级财务计算时也是如此。事实上,贸易公司聘请数学家和物理学家来构建交易算法。但能够进行此类分析的人非常罕见。因此,对于大多数简单的财务计算,人们被告知只需计算整数便士。
答案 2 :(得分:2)
这是一个扩展的评论,而不是答案。
我想给OP一个简单的挑战,并有机会证明"从总和中删除小数点的可行性和有效性(如果使用小数或负数的算术很难计算),然后将小数点放回最终答案中#34;用于科学和工程编程。当然,这正是像Java的BigDecimal这样的十进制数系统所做的事情,软件跟踪小数点的位置。
许多科学和工程计划涉及求解线性方程组。更多涉及类似的线性代数操作。因此,线性方程解是科学计算的常用基准形式。
LINPACK 1000测量系统解决1000个线性方程组的速度。它允许更改求解器,因此OP可以编写一个不在求解器内使用二进制浮点的实现,并获得有效的结果。源代码以多种语言提供,以提供一个起点。我建议至少瞄准使用IEEE 64位二进制浮点常规实现的精度。输入以二进制浮点格式提供,但每个二进制浮点数都有精确的十进制表示。
许多系统都公布了结果 - 请参阅Jack Dongarra撰写的各种论文,例如2013年的论文Performance of Various Computers Using Standard Linear Equations Software。将OP的精度和性能结果与使用二进制浮点的可比较硬件的结果进行比较应该没有困难。
答案 3 :(得分:1)
只想投入我的两分钱:
float
- 货币价值变量时的麻烦不是因为使用浮点符号而是因为它们使用二进制浮点变量而不是&# 39; t很好地映射到精确十进制值。floor((0.1+0.7)*10)
实际为7
且0.1
为0.1 +- 10%
时,0.7
没有意义,或者0.7 +- 5%
会产生{{1}}。< / LI>