javascript - 浮点表示似乎可以正确地进行整数运算——为什么?

标签 javascript c++ floating-point

我一直在玩弄 float ,根据我过去对它们的了解,0.1 + 0.2 最终变成了类似 0.30000000000000004 并不让我吃惊。

然而, 让我感到惊讶的是,整数运算总是似乎 工作得很好并且没有任何这些工件。

我首先在 JavaScript(node.js 中的 Chrome V8)中注意到了这一点:

0.1 + 0.2 == 0.3 // false, NOT surprising
123456789012 + 18 == 123456789030  // true
22334455667788 + 998877665544 == 23333333333332 // true
1048576 / 1024 == 1024  // true

C++(Mac OS X 上的 gcc)似乎具有相同的属性。

最终结果似乎是整数——找不到更好的词了——有效。只有当我开始使用十进制数字时,事情才会变得不稳定。

这是设计的一个特征、一个数学产物,还是编译器和运行时环境所做的一些优化?

最佳答案

Is this is a feature of the design, an mathematical artifact, or some optimisation done by compilers and runtime environments?

这是实数的特征。现代代数的一个定理(现代代数,不是高中代数;数学专业的学生在完成基本微积分和线性代数类(class)后会学习现代代数)说对于一些正整数b,任何正实数r 可以表示为 r = a * bp,其中 a 是在 [1,b) 和 p 中是某个整数。例如,102410 = 1.02410*103。正是这个定理证明了我们使用科学计数法是合理的。

那个数字 a 可以分类为终结(例如 1.0)、重复(1/3=0.333...)或非重复(pi 的表示)。终端号码这里有一个小问题。任何终端号码也可以表示为重复号码。例如,0.999...和 ​​1 是相同的数字。这种表示形式上的歧义可以通过指定可以表示为终端号的数字来表示来解决。

您所发现的是所有整数在任何基数中都具有终结表示这一事实的结果。

此处存在一个问题,即实数在计算机中的表示方式。正如 intlong long int 不代表所有整数一样,floatdouble 也不代表所有整数所有的实数。大多数计算机上用来表示实数 r 的方案是以 r = a*2p 的形式表示sup>,但尾数(或尾数)a 被 chop 为特定位数,指数 p 被限制为某个有限数。这意味着某些整数无法准确表示。例如,尽管 googol (10100) 是一个整数,但它的浮点表示并不精确。 googol 的基数 2 表示是一个 333 位数字。此 333 位尾数被 chop 为 52+1 位。

这样做的结果是 double 算术不再精确,即使对于大于 253 的整数也是如此。尝试使用 unsigned long long int 类型对 253 和 264 之间的值进行实验。您会发现 double 算法对于这些大整数不再精确。

关于javascript - 浮点表示似乎可以正确地进行整数运算——为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13064715/

相关文章:

javascript - 使用 react-router 处理 401 未授权代码

c++ - 在将参数传递给基类时使用 std::move()

php - 如何修复 PhpExcel 额外的小数点错误?

c++ - 这个输入中的 float 和 double 有什么区别?

python - 如何在 python 中计算具有 unicode 组件的字符串的数值?

javascript - Highcharts : add images to top of chart on every column

javascript - 文本区域中的行高(IE7)

javascript - 给定一个外盒和内盒,确定内盒的位置

c++ - 程序入口点 sqlite3_db_filname 无法位于 dll 中

c++ - boost asio 和条件变量——奇怪的输出