- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
假设我们有 2 个常量 A
& B
和一个变量 i
,都是 64 位整数。我们要计算一个简单的常见算术运算,例如:
i * A / B (1)
为了简化问题,我们假设变量 i
总是在 [INT64_MIN*B/A, INT64_MAX*B/A]
范围内,所以最后算术运算 (1) 的结果不会溢出(即:fits 在 [INT64_MIN, INT64_MAX]
范围内)。
另外,i
被认为更可能在 friendly 范围 Range1 = [INT64_MIN/A, INT64_MAX/A]
(即:接近 0),但是 i
可能(不太可能)超出此范围。在第一种情况下,i * A
的简单整数计算不会溢出(这就是我们称范围 friendly 的原因);在后一种情况下,i * A
的简单整数计算会溢出,导致 (1) 的计算结果错误。
计算操作 (1) 的“最安全”和“最有效”的方式是什么(其中“最安全”的意思是:保持精确性或至少具有不错的精度,而“最有效”的意思是:平均计算时间最短),前提是 i
更有可能在 friendly 范围 Range1。
目前,代码中目前实现的解决方案如下:
(int64_t)((double)A / B * i)
哪个解决方案非常安全(没有溢出),但不准确(由于双有效位 53 位限制导致精度损失)并且非常快,因为双除法 (double)A/B
是在编译时预先计算的,只允许在运行时计算双倍乘法。
最佳答案
如果您无法在所涉及的范围上获得更好的界限,那么您最好遵循 iammilind's advice使用 __int128
.
原因是,否则您将必须实现字到双字乘法和逐字除法的完整逻辑。 Intel 和 AMD 处理器手册包含有用的信息和现成的代码,但它涉及到相当多的内容,并且使用 C/C++ 而不是汇编程序会使事情变得更加复杂。
所有优秀的编译器都将有用的原语公开为内在函数。 Microsoft's list似乎不包含类似 muldiv 的原语,但 __mul128
内在函数将 128 位乘积的两半作为两个 64 位整数提供。基于此,您可以执行两位数除以一位数的长除法,其中一位“数字”将是一个 64 位整数(通常称为“肢体”,因为大于一位数但仍然只是整体的一部分)。仍然相当复杂,但比使用纯 C/C++ 好得多。然而,就便携性而言,它并不比使用 __int128
好。直接地。至少这样编译器实现者已经为您完成了所有艰苦的工作。
如果您的应用程序域可以为您提供有用的界限,例如 (u % d) * v
不会溢出就可以使用身份了
(u * v) / d = (u / d) * v + ((u % d) * v) / d
在哪里 /
表示整数除法,只要 u 是非负数且 d 是正数(否则您可能会违反运算符 %
的语义所允许的余地)。
在任何情况下,您都可能必须分离出操作数的符号并使用无符号运算,以便找到可以利用的更有用的机制 - 或规避编译器的破坏,例如您提到的饱和乘法。有符号整数操作的溢出会调用未定义的行为,编译器可以自由地做任何他们想做的事情。相比之下,无符号类型的溢出是明确定义的。
此外,对于无符号类型,您可以使用 s = a (+) b
之类的规则。 (其中 (+)
可能是溢出的无符号加法)您将拥有 s == a + b
或 s < a && s < b
,它可以让您通过廉价的操作在事后检测溢出。
但是,您不太可能在这条道路上走得更远,因为所需的努力很快就会接近(甚至超过)我之前提到的实现双肢手术的努力。只有对应用程序域进行彻底分析才能提供规划/部署此类快捷方式所需的信息。在一般情况下,在你给定的范围内,你几乎不走运。
关于c++ - 计算可能溢出的整数运算的最安全和最有效的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36826664/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!