C 或 C++ 中乘法和除法的较高部分?

2024-02-13

当我在汇编中将一对 4 字节整数相乘时,结果的较低部分在 EAX 中,较高部分在 EDX 中。如果我使用 C 或 C++ 并且我想获得更高的部分,是否可以不使用内联汇编?

是否可以以同样的方式从 EAX 获得整数除法结果,从 EDX 获得模数结果,而无需在 C 或 C++ 中重复除法?我其实只知道先做a/b进而a%b,而在汇编程序中,两个结果都是在同一操作中给出的。


你可以用 C 语言这样轻松地做到这一点:

#include <stdint.h>

uint32_t a, b;  // input
uint64_t val = (uint64_t)a * b;
uint32_t high = val >> 32, low = val;

让编译器生成尽可能最好的代码。现代优化器确实很擅长。手工编码的程序集通常看起来更好但性能更差。

正如 Pete Becker 所评论的,上述内容取决于类型的可用性uint32_t and uint64_t。如果您坚持顽固的可移植性(假设您正在DS9K),您可以改为使用类型uint_least32_t and uint_least64_t or uint_fast32_t and uint_fast64_t在 C99 下始终可用,但您需要一个额外的掩码,如果不需要,它将被优化:

#include <stdint.h>

uint_fast32_t a, b;  // input
uint_fast64_t val = (uint_fast64_t)a * b;
uint_fast32_t high = (val >> 32) & 0xFFFFFFFF, low = val & 0xFFFFFFFF;

关于除法,可以使用C99库函数div, ldiv or lldiv在一次调用中执行有符号除法和余数运算。如果可能的话,在特定操作数类型的目标架构上,除法/模组合将在一次操作中实现。

编写两个表达式并依靠编译器来检测模式并生成使用单个 IDIV 操作码的代码可能会更有效:

struct divmod_t { int quo, rem; };
struct divmod_t divmod(int num, int denom) {
    struct divmod_t r = { num / denom, num % denom };
    return r;
}

测试于Matt Godbolt 的编译器浏览器 https://godbolt.org/g/oOvl17显示 clang 和 gcc 都生成一个idiv该代码的说明位于-O3.

您可以将这些除法之一转化为乘法:

struct divmod_t { int quo, rem; };
struct divmod_t divmod2(int num, int denom) {
    struct divmod_t r;
    r.quo = num / denom;
    r.rem = num - r.quo * denom;
    return r;
}

请注意,上述函数不会检查潜在的溢出,这会导致未定义的行为。如果发生溢出denom = 0 and if num = INT_MIN and denom = -1.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C 或 C++ 中乘法和除法的较高部分? 的相关文章

  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 重载 (c)begin/(c)end

    我试图超载 c begin c end类的函数 以便能够调用 C 11 基于范围的 for 循环 它在大多数情况下都有效 但我无法理解和解决其中一个问题 for auto const point fProjectData gt getPoi
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • 对于某些 PDF 文件,LoadIFilter() 返回 -2147467259

    我正在尝试使用 Adob e IFilter 搜索 PDF 文件 我的代码是用 C 编写的 我使用 p invoke 来获取 IFilter 的实例 DllImport query dll SetLastError true CharSet
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • DotNetZip:如何提取文件,但忽略zip文件中的路径?

    尝试将文件提取到给定文件夹 忽略 zip 文件中的路径 但似乎没有办法 考虑到其中实现的所有其他好东西 这似乎是一个相当基本的要求 我缺少什么 代码是 using Ionic Zip ZipFile zf Ionic Zip ZipFile
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • 现代编译器是否优化乘以 1 和 -1

    如果我写 template
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • Android dex2oat build:错误:Dex2oat 无法编译启动映像

    构建安卓9 0 错误 Dex2oat 无法编译启动映像 引导类路径可能不一致 使用 ART BOOT IMAGE EXTRA ARGS runtime arg verbose 重建 验证程序以查看验证错误 只需禁用优化sse4 2 popc
  • 为什么结构中的 Box 需要“显式生命周期限制”?

    编者注 此代码在之后不再产生相同的错误RFC 599 https github com rust lang rfcs blob master text 0599 default object bound md已实施 但答案中讨论的概念仍然有
  • 使用 Angularjs 加载文本的 Bootstrap 按钮

    在使用 bootstrap 和 jquery 的非角度应用程序中 我可以创建如下按钮
  • http://timestamp.geotrust.com/tsa 是否不再可用于 SignTool?

    我们在构建服务器上签署可执行文件 突然构建服务器无法构建并给出错误 SignTool 错误 无法到达指定的时间戳服务器或返回无效响应 将时间戳服务器更改为后http sha256timestamp ws symantec com sha25
  • 使用“printf”返回字符串,而不是打印它

    这可能听起来很奇怪 但事实就是如此 我喜欢使用这种在 php 中构建字符串的技术 printf This is 1 s this is 2 s myFunction1 myFunction2 显然 每当调用函数时 这都会直接打印结果 但我想
  • 有没有办法在Windows中模拟LD_LIBRARY_PATH?

    我有一个程序可以做一些图形 当我以交互方式运行它时 我希望它使用系统中的 OpenGL 来提供硬件加速图形 当我批量运行它时 我希望能够将其重定向以使用 Mesa GL 库 以便我可以使用 OSMesa 功能渲染到屏幕外缓冲区 如果选择了批
  • 如何在 VBA 2010 上导出图像之前裁剪图像

    我有一个子例程可以很好地导出从 Excel 中的某个范围内获取的图像 但我遇到了一个问题 即使我设法使图表对象透明并且没有边框 导出的图像有一个我希望在导出之前裁剪很多未使用的区域 Sub BtnSaveFile Click Dim RgE
  • 努力在 Glassfish 上创建 MySQL 连接池

    我以前已经这样做过 但由于某种原因 我在创建这个连接池时确实遇到了一些困难 当我在创建连接池后 ping 连接池时 出现以下错误 Ping Connection Pool for bondsaver is Failed Ping faile
  • 远程连接 Neo4j 服务器

    我相信创建远程连接的方法是更改 此行conf neo4j server properties 特别是删除注释并重新启动服务器 org neo4j server webserver address 0 0 0 0 我的网址是https 0 0
  • 启动 Nexus docker 镜像时如何设置管理员用户/密码

    当在 Nexus 2 docker 镜像中启动时 https hub docker com r sonatype nexus https hub docker com r sonatype nexus 如何配置它以将默认管理员用户密码更改为
  • 在 Clojure 中搜索 xml

    我有以下示例 xml
  • 有没有办法在 Protractor 测试中绕过 Chrome 地理定位对话框?

    在使用量角器自动化应用程序时 我遇到了这个问题 打开主页后 我会看到带有 阻止 允许 按钮的地理位置对话框 如果不选择任一选项 该对话框就无法继续 事实证明 这个对话框不是警报的实例 这就是为什么browser switchTo alert
  • 新 Activity 的 onStart 在父 Activity 的 onStop 之前调用

    我有一份申请 我用startActivity 开始活动 谁能真正告诉我为什么系统会调用onStart 首先是新 Activity 而不是父活动onStop 这可能吗 没有系统错误 我找到了在 onStart 之后直接调用 Fragment
  • 从文件生成频率表

    给定一个每行包含一个数字的输入文件 我如何计算某个项目在该文件中出现的次数 cat input txt 1 2 1 3 1 0 期望的输出 gt 1 3 1 1 cat output txt 0 1 1 3 2 1 3 1 如果该解决方案也
  • Postgres SELECT 数组中的值

    我有一个看起来像这样的 postgres 表 缩短 id serial col1 character varying 1 Life Health VA Data 我正在尝试执行以下操作 SELECT FROM mytable WHERE L
  • 析构函数的执行顺序?

    我知道c 中的析构函数没有执行顺序 我在几个类中使用以下结构 它是为了破坏实例和静态信息 public class MyClass private static readonly Destructor DestructorObject ne
  • =importXML() 中的 xpath 用于提取元描述

    我正在尝试使用 Xpath 使用 Google Sheets 从网页中提取元描述 我正在努力提取标题 importXml www example com title 以下是我的两个学习来源 http seogadget co uk play
  • 简单 MySQL 子查询性能

    考虑 2 个 MySQL 查询 SELECT ue userid e courseid FROM SELECT id courseid FROM mdl enrol WHERE status 0 AND courseid IN 46 e I
  • 使用 ADO .NET 调用 SQL 函数

    我想要在 SQL Server 中创建调用函数 它接收两个参数并返回一个整数 当我调用存储过程时 我使用以下代码 sqlcmd CommandType CommandType StoredProcedure sqlcmd CommandTe
  • C 或 C++ 中乘法和除法的较高部分?

    当我在汇编中将一对 4 字节整数相乘时 结果的较低部分在 EAX 中 较高部分在 EDX 中 如果我使用 C 或 C 并且我想获得更高的部分 是否可以不使用内联汇编 是否可以以同样的方式从 EAX 获得整数除法结果 从 EDX 获得模数结果