问题标签 [extended-precision]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - 是否有文档描述 Clang 如何处理过多的浮点精度?
当唯一允许使用的浮点指令是 387 时,几乎不可能 (*) 以合理的成本提供严格的 IEEE 754 语义。当希望让 FPU 在完整的 64 位有效位上工作以使该long double
类型可用于扩展精度时,这尤其困难。通常的“解决方案”是以唯一可用的精度进行中间计算,并在或多或少定义明确的情况下转换为较低的精度。
根据 Joseph S. Myers 在2008 年发给 GCC 邮件列表的帖子中的解释,最新版本的 GCC 处理了中间计算中的过度精度。gcc -std=c99 -mno-sse2 -mfpmath=387
据我所知,这个描述使编译的程序完全可以预测,直到最后一点。如果碰巧没有,这是一个错误,它将被修复:Joseph S. Myers 在他的帖子中声明的意图是使其可预测。
它是否记录了 Clang 如何处理超额精度(例如何时-mno-sse2
使用该选项)以及在哪里?
(*) 编辑:这是夸大其词。当允许将 x87 FPU 配置为使用 53 位有效位时,模拟 binary64有点烦人但并不难。
在 R.. 下面的评论之后,这是我与我拥有的最新版本的 Clang 的简短交互日志:
assembly - 在 32 机器上添加 32 位数字,在两个寄存器中扩展为 64 位和
如何在 32 位机器上添加几个 32 位数字但不损失精度,即在 64 位“伪寄存器”eax:edx
中。使用 Intel 语法汇编器。
c++ - 浮点 NaN 取决于 C++ 中不相关的异常处理
真的很奇怪:
好的,由于一些优化,第二个 c 结果可能为 0。
但是:当我删除 try/catch 块时,第二个 c 仍然是 NaN!为什么会有这种不同的行为???我的编译器是 VC++ 2010 Express。操作系统 Windows 7 64 位。我只使用标准库,如 iostream 和 cmath。
编辑:我的第一个观察是空控制台应用程序的 Debug+Win32 默认设置。使用 Release+Win32 的结果是:第一个 c 0,第二个 c NaN - 无论 try/catch 是否存在!概括:
编辑 2:当我/fp:strict
在 C++/代码生成中设置开关时,结果与 Debug+Win32 相同,但使用 Release+Win32 时,c = a * b; // NaN
无论c = (1/sigma) * exp(-1/sigma); // 0
是否尝试,它都会更改为。我不明白为什么它保留NaN+NaN
在 Debug+Win32 并且没有之前的尝试。当结果与 Release 不同时,如何调试必须是浮点安全的程序/fp:strict
取决于先前的尝试?
编辑 3:这里有一个完整的程序:
assembly - 什么是最快的 x86-64 汇编语言除法算法?
我正在用 x86-64 汇编语言编写代码库,为s0128
, s0256
, s0512
,s1024
有符号整数类型和f0128
, f0256
, f0512
,f1024
浮点类型提供所有常规的按位、移位、逻辑、比较、算术和数学函数。到目前为止,我正在研究有符号整数类型,因为浮点函数可能会调用一些为整数类型编写的内部例程。
到目前为止,我已经编写并测试了执行各种一元运算符、比较运算符以及加法、减法和乘法运算符的函数。
现在我正在尝试决定如何为除法运算符实现功能。
我的第一个想法是,“Newton-Raphson 一定是最好的方法”。为什么?因为给定一个好的种子(开始猜测)它会很快收敛,我想我应该能够弄清楚如何在操作数上执行本机 64 位除法指令以获得出色的种子值。事实上,如果种子值精确到 64 位,要获得正确答案只需:
然而,对这个问题的更多思考让我想知道。例如,我记得我编写的核心例程,它对所有大整数类型执行乘法运算:
更广泛的数据类型的操作增长相当可观,即使循环相当短且高效(包括缓存方式)。此循环仅将结果的每个 64 位部分写入一次,并且从不读回结果的任何部分以进行进一步处理。
这让我开始思考是否更传统的移位和减法类型划分算法可能更快,尤其是对于较大的类型。
我的第一个想法是这样的:
#1:为了计算每一位,如果除数小于或等于被除数,则通常从除数中减去除数。好吧,通常我们可以通过仅检查其最重要的 64 位部分来确定除数肯定小于或肯定大于被除数。只有当这些 ms64 位部分相等时,例程才必须检查下一个较低的 64 位部分,只有当它们相等时,我们才必须检查更低的部分,依此类推。因此,几乎在每次迭代中(计算结果的每一位),我们都可以大大减少为计算该测试而执行的指令。
#2:但是……平均而言,大约 50% 的时间我们会发现我们需要从被除数中减去除数,所以无论如何我们都需要减去它们的整个宽度。在这种情况下,我们实际上执行了比传统方法更多的指令(我们首先将它们相减,然后测试标志以确定除数是否 <= 被除数)。因此,一半的时间我们实现储蓄,一半的时间我们实现亏损。在大型类型s1024
(如包含 -16-64 位组件)上,节省大量且损失很小,因此这种方法应该实现大量净节省。在像s0128
(包含 -2- 64 位组件)这样的小型类型上,节省很少,损失很大,但不是很大。
所以,我的问题是,“什么是最有效的划分算法”,给出:
注意:我的猜测是,实际的实现只会对无符号整数进行操作。在乘法的情况下,将负操作数转换为正数,然后执行无符号乘法,然后如果恰好一个原始操作数为负数,则将结果取反更容易和更有效(也许)。但是,如果它是有效的,我会考虑一个有符号整数算法。
注意:如果我的浮点类型 ( f0128
, f0256
, f0512
, f1024
) 的最佳答案不同,请解释原因。
注意:我的内部核心无符号乘法例程对所有这些整数数据类型执行乘法运算,产生一个双倍宽度的结果。换句话说:
我的代码库为每个有符号整数数据类型提供了两个版本的乘法:
这与我的代码库的“永不丢失精度”和“永不溢出”的策略一致(当答案因精度丢失或上溢/下溢而无效时返回错误)。但是,当调用双宽度返回值函数时,不会出现此类错误。
c++ - 超精度的 C++ 处理
我目前正在查看执行多精度浮点运算的代码。为了正常工作,该代码需要在明确定义的点处将值减少到它们的最终精度。因此,即使将中间结果计算到80 位扩展精度浮点寄存器,在某些时候也必须将其舍入到64 位双精度以进行后续操作。
代码使用宏INEXACT
来描述这个需求,但没有一个完美的定义。gcc 手册提到-fexcess-precision=standard
作为强制转换和赋值操作定义明确的精度的一种方法。但是,它还写道:
'-fexcess-precision=standard' 未针对 C 以外的语言实现
现在我正在考虑将这些想法移植到 C++(如果有人知道现有实现,欢迎发表评论)。所以看来我不能将该开关用于 C++。但是在没有任何开关的情况下,g++ 默认行为是什么?是否有更多类似 C++ 的方法来控制超精度的处理?
我想对于我当前的用例,我可能会-mfpmath=sse
在任何情况下使用,据我所知,这不会导致任何过度的精度。但我还是很好奇。
gcc - 哪些 gcc 版本支持 __int128 内在类型?
在gcc docs 下,128 位整数是:
作为扩展,整数标量类型
__int128
支持具有足够宽以容纳 128 位的整数模式的目标。只需写__int128
一个有符号的 128 位整数,或unsigned __int128
一个无符号的 128 位整数。GCC 不支持为
__int128
具有小于 128 位宽的 long long 整数的目标表示类型的整数常量。
我想知道哪个 gcc 版本添加了对这种类型的支持,或者是否有一个可以直接用于测试其存在的宏。
fortran - 非常大的实数的精度问题 - Fortran
我目前试图解决的问题涉及计算 10 模(n)的顺序,其中 n 可以是小于 1000 的任何数字。我有一个函数可以做到这一点,但是,我无法获得准确的结果随着订单价值的增加。
只要订单足够小,该函数就可以正常工作,但对于大订单返回不正确的值。所以我坚持在终端的一些输出中定位问题,并发现当我使用幂运算时,我的实数的准确性受到了损害。
我在函数中声明了所有变量,并在程序中将其作为 real(kind=nkind) 进行了测试,其中 nkind = selected_real_kind(p=18, r=308)。任何显式引用的数字也被声明为,例如,1.0_nkind。但是,当我打印出 10**n for n 从 1 开始计数时,我发现在 10**27 处,该值是正确的。但是, 10**28 给出 9999999999999999999731564544。所有更高的幂都类似地扭曲,这种不准确性是我问题的根源。
所以,我的问题是,有没有办法解决这个错误?我不知道有什么方法可以使用比我已经在计算中使用的更高的精度。
谢谢,肖恩
*编辑:代码中没有什么可看的,但你去吧:
sse - 实用的 BigNum AVX/SSE 可能吗?
SSE/AVX 寄存器可以被视为整数或浮点 BigNums。也就是说,人们完全可以忽略存在车道。是否存在一种简单的方法来利用这种观点并将这些寄存器单独或组合用作 BigNums?我问是因为从我对 BigNum 库的了解来看,它们几乎普遍地在数组上存储和执行算术运算,而不是在 SSE/AVX 寄存器上。可移植性?
例子:
假设您将 SSE 寄存器的内容作为密钥存储在 a 中std::set
,您可以将这些内容作为 BigNum 进行比较。
delphi - 将扩展值转换为时间
我想将扩展值转换为时间。DecimalSeparator 之前是小时,小数分隔符之后是分钟数字
我做了这个功能,但我得到了 1,41666666666667 --> 1:24 它必须是 25 分钟
当我使用精确的 1,41666666666667 时,我得到 1:25 但我必须转换的值来自肥皂输入界面作为双精度(oPostCalculationDay.DirectAssignedWorkTime)。
我在调试模式下得到的值 = 1,41666666666667
我在想类似于浮点数
但是我必须使用的最佳方法是什么?Roundto -14 因为 1,41666666666667 是其他东西分隔符之后的 14 个数字?
j - 在 J 中,我怎样才能找到平方根的扩展精度整数下限
%:
我知道当我对一个不产生整数的数字求平方根 ( ) 时,我的答案是浮点数。我正在寻找<.
平方根的下限 ( ) 以获得整数结果。J 是否有内置的方法来实现这一点?我需要求助于循环来找到我的答案吗?
折腾一些扩展精度 ( x:
) 请求当然不会这样做。