当我在程序集中乘以一对4字节整数时,结果的下半部分在EAX中,EDX中的较高部分.如果我在C或C中,我想获得更高的部分,是否可能没有使用内联汇编?

以同样的方式可以得到EAX的整数除法结果和EDX的模数结果,而不会重复C或C的划分?我实际上只知道做第一个a / b,然后是一个%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和uint64_t类型的可用性.如果您坚持使用硬盘可移植性(例如您在DS9K上进行编程),则可以使用在C99下始终可用的类型uint_least32_t和uint_least64_t或uint_fast32_t和uint_fast64_t,但是您需要一个额外的掩码,如果不需要:

#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或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’s compiler explorer显示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,并且如果num = INT_MIN和denom = -1,则发生溢出.

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

  1. Html5原创俄罗斯方块(基于canvas)

    这篇文章主要介绍了Html5原创俄罗斯方块(基于canvas)的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. swift 数据类型转换 string 转换为 int, int转换为string 等等 string转换为nsmutablestring

    bytheway:刚接触swift不就,学到的东西比较浅~~,但是有问题可以在评论里说说,我每天上,一起成长~~早晚小牛长成大牛,~more牛~~~牛的立方~~gogo

  3. 【swift_1】swift基本语法及事例Demo

    语法类的文档网上比较多,我这里参考:Swift基本语法事例Demo:链接:http://pan.baidu.com/s/1jGCINCq密码:5mdk语法须知2个不需要不需要编写main函数:全局作用域中的代码会被自动当做程序的入口点(从上往下执行)不需要在每一条语句后面加上分号letradius=10你喜欢的话,也可以加上letradius=10;有一种情况必须加分号:同一行代码上有多条语句时1

  4. 数组的enumerate(swift)

    数组的enumerateby伍雪颖letarr:Array=[1,2,216)">3,216)">4,216)">5]varresult=0forinenumerate{result+=num}println

  5. swift语言的学习笔记十二(初始化方法)

    所以Swift有了超级严格的初始化方法。与designated初始化方法对应的是在init前加上convenience关键字的初始化方法。所有的convenience初始化方法都必须调用同一个类中的designated初始化完成设置,另外convenience的初始化方法是不能被子类重写或从子类中以super的方式被调用的。这样的一个最大的好处是可以保证依赖于某个designated初始化方法的convenience一直可以被使用。这在要求子类不直接使用父类中的convenience初始化方法时会非常有帮

  6. Swift 柯里化(currying)和反柯里化(uncurrying)

    //DemoofcurryingfuncaddTwoNums(a:Int)(num:Int)->Int{returna+num}letaddToFour=addTwoNums(4)letresult=addToFour(num:6)print("result:\(result)")funcgreaterThan(comparor:Int)(input:Int)->Bool{returninput>

  7. 从零学习Swift&lt;2&gt;

    ,可以强行解包注意:必须要确保解包后的值不是nil,否则会报错常见错误unexpectedlyfoundnilwhileunwrappinganOptionalvalue翻译在[解包]一个可选值时发现nil??运算符可以用于判断变量/常量的数值是否是nil,如果是则使用后面的值替代在使用Swift开发时,??

  8. 挺好的一篇总结文(等有空时看看)

    最近几天的感受是,Swift并不像我上一篇表达自己初步看法的文章里所说的那样,相对于objc来说有更好的学习曲线。另外一种类型是复合类型,包括函数和多元组。它们在使用的时候不会被命名,而是由Swift内部自己定义。在Swift的世界中,一切看得到的东西,都一定属于某一种类型。这也正式Swift的类型的一种很常见的组织方式。而当我们检查到Array的时候,发生了一点神奇的事情。这里的原因其实在Apple的官方文档中有一些说明。

  9. Swift 338. Counting Bits

    Givenanonnegativeintegernumbernum.Foreverynumbersiintherange0≤i≤numcalculatethenumberof1'sintheirbinaryrepresentationandreturnthemasanarray.Example:Fornum=5youshouldreturn[0,1,2,2].题意:给定num,计算从0到num中的

  10. swift 中常用的进制转换

随机推荐

  1. 从C到C#的zlib(如何将byte []转换为流并将流转换为byte [])

    我的任务是使用zlib解压缩数据包(已接收),然后使用算法从数据中生成图片好消息是我在C中有代码,但任务是在C#中完成C我正在尝试使用zlib.NET,但所有演示都有该代码进行解压缩(C#)我的问题:我不想在解压缩后保存文件,因为我必须使用C代码中显示的算法.如何将byte[]数组转换为类似于C#zlib代码中的流来解压缩数据然后如何将流转换回字节数组?

  2. 为什么C标准使用不确定的变量未定义?

    垃圾价值存储在哪里,为什么目的?解决方法由于效率原因,C选择不将变量初始化为某些自动值.为了初始化这些数据,必须添加指令.以下是一个例子:产生:虽然这段代码:产生:你可以看到,一个完整的额外的指令用来移动1到x.这对于嵌入式系统来说至关重要.

  3. 如何使用命名管道从c调用WCF方法?

    更新:通过协议here,我无法弄清楚未知的信封记录.我在网上找不到任何例子.原版的:我有以下WCF服务我输出添加5行,所以我知道服务器是否处理了请求与否.我有一个.NET客户端,我曾经测试这一切,一切正常工作预期.现在我想为这个做一个非托管的C客户端.我想出了如何得到管道的名称,并写信给它.我从here下载了协议我可以写信给管道,但我看不懂.每当我尝试读取它,我得到一个ERROR_broKEN_P

  4. “这”是否保证指向C中的对象的开始?

    我想使用fwrite将一个对象写入顺序文件.班级就像当我将一个对象写入文件时.我正在游荡,我可以使用fwrite(this,sizeof(int),2,fo)写入前两个整数.问题是:这是否保证指向对象数据的开始,即使对象的最开始可能存在虚拟表.所以上面的操作是安全的.解决方法这提供了对象的地址,这不一定是第一个成员的地址.唯一的例外是所谓的标准布局类型.从C11标准:(9.2/20)Apointe

  5. c – 编译单元之间共享的全局const对象

    当我声明并初始化一个const对象时.两个cpp文件包含此标头.和当我构建解决方案时,没有链接错误,你会得到什么如果g_Const是一个非const基本类型!PrintInUnit1()和PrintInUnit2()表明在两个编译单元中有两个独立的“g_Const”具有不同的地址,为什么?

  6. 什么是C名称查找在这里? (&amp;GCC对吗?)

    为什么在第三个变体找到func,但是在实例化的时候,原始变体中不合格查找找不到func?解决方法一般规则是,任何不在模板定义上下文中的内容只能通过ADL来获取.换句话说,正常的不合格查找仅在模板定义上下文中执行.因为在定义中间语句时没有声明func,并且func不在与ns::type相关联的命名空间中,所以代码形式不正确.

  7. c – 在输出参数中使用auto

    有没有办法在这种情况下使用auto关键字:当然,不可能知道什么类型的.因此,解决方案应该是以某种方式将它们合并为一个句子.这可用吗?解决方法看起来您希望默认初始化给定函数期望作为参数的类型的对象.您无法使用auto执行此操作,但您可以编写一个特征来提取函数所需的类型,然后使用它来声明您的变量:然后你就像这样使用它:当然,只要你重载函数,这一切都会失败.

  8. 在C中说“推动一切浮动”的确定性方式

    鉴于我更喜欢将程序中的数字保留为int或任何内容,那么使用这些数字的浮点数等效的任意算术最方便的方法是什么?说,我有我想写通过将转换放在解析的运算符树叶中,无需将表达式转化为混乱是否可以使用C风格的宏?应该用新的类和重载操作符完成吗?解决方法这是一个非常复杂的表达.更好地给它一个名字:现在当您使用整数参数调用它时,由于参数的类型为double,因此使用常规的算术转换将参数转换为double用C11lambda……

  9. objective-c – 如何获取未知大小的NSArray的第一个X元素?

    在objectiveC中,我有一个NSArray,我们称之为NSArray*largeArray,我想要获得一个新的NSArray*smallArray,只有第一个x对象…

  10. c – Setprecision是混乱

    我只是想问一下setprecision,因为我有点困惑.这里是代码:其中x=以下:方程的左边是x的值.1.105=1.10应为1.111.115=1.11应为1.121.125=1.12应为1.131.135=1.14是正确的1.145=1.15也正确但如果x是:2.115=2.12是正确的2.125=2.12应为2.13所以为什么在一定的价值是正确的,但有时是错误的?请启发我谢谢解决方法没有理由期望使用浮点系统可以正确地表示您的帖子中的任何常量.因此,一旦将它们存储在一个双变量中,那么你所拥有的确切的一

返回
顶部