精华内容
下载资源
问答
  • 性能 - 我应该使用乘法还是除法?这是一个愚蠢有趣的问题:让我们说我们必须执行一个简单的操作,我们需要一半的变量。 通常有两种方法:y = x / 2.0;// or...y = x * 0.5;假设我们正在使用该语言提供的标准运算符...

    性能 - 我应该使用乘法还是除法?

    这是一个愚蠢有趣的问题:

    让我们说我们必须执行一个简单的操作,我们需要一半的变量值。 通常有两种方法:

    y = x / 2.0;

    // or...

    y = x * 0.5;

    假设我们正在使用该语言提供的标准运算符,哪一个具有更好的性能?

    我猜测乘法通常更好,所以我在编码时会尽力坚持,但我想证实这一点。

    虽然我个人对Python 2.4-2.5的答案感兴趣,但也可以发布其他语言的答案! 如果您愿意,也可以随意发布其他更好的方式(比如使用按位移位运算符)。

    25个解决方案

    73 votes

    蟒蛇:

    time python -c 'for i in xrange(int(1e8)): t=12341234234.234 / 2.0'

    real 0m26.676s

    user 0m25.154s

    sys 0m0.076s

    time python -c 'for i in xrange(int(1e8)): t=12341234234.234 * 0.5'

    real 0m17.932s

    user 0m16.481s

    sys 0m0.048s

    乘法快33%

    LUA:

    time lua -e 'for i=1,1e8 do t=12341234234.234 / 2.0 end'

    real 0m7.956s

    user 0m7.332s

    sys 0m0.032s

    time lua -e 'for i=1,1e8 do t=12341234234.234 * 0.5 end'

    real 0m7.997s

    user 0m7.516s

    sys 0m0.036s

    => 没有真正的区别

    LuaJIT:

    time luajit -O -e 'for i=1,1e8 do t=12341234234.234 / 2.0 end'

    real 0m1.921s

    user 0m1.668s

    sys 0m0.004s

    time luajit -O -e 'for i=1,1e8 do t=12341234234.234 * 0.5 end'

    real 0m1.843s

    user 0m1.676s

    sys 0m0.000s

    =>它只快了5%

    结论:在Python中,它的乘法速度比分频更快,但随着使用更高级的VM或JIT越来越接近CPU,优势就消失了。 未来的Python VM很可能会使它变得无关紧要

    Javier answered 2019-07-07T03:17:09Z

    63 votes

    始终使用最清楚的东西。 你做的其他事情就是试图超越编译器。 如果编译器完全是智能的,它会尽力优化结果,但是没有什么可以让下一个人不讨厌你的糟糕的位移解决方案(顺便说一下,我喜欢点操作,它很有趣。但是 好玩!=可读)

    过早优化是万恶之源。 永远记住三个优化规则!

    不要优化。

    如果您是专家,请参阅规则#1

    如果您是专家并且可以证明需要,那么请使用以下过程:

    编码未经优化

    确定有多快"足够快" - 注意哪个用户要求/故事需要该指标。

    写一个速度测试

    测试现有代码 - 如果速度足够快,您就完成了。

    重新编码优化

    测试优化代码。 如果它不符合指标,则将其丢弃并保留原始指标。

    如果符合测试,请将原始代码保留为注释

    此外,在不需要内部循环时执行删除内部循环或在数组上选择链接列表以进行插入排序等操作不是优化,只是编程。

    Bill K answered 2019-07-07T03:19:11Z

    47 votes

    我认为这是非常挑剔的,以至于你最好不要做任何使代码更具可读性的东西。 除非你执行数千次,甚至数百万次的操作,否则我怀疑任何人都会注意到这种差异。

    如果你真的需要做出选择,基准测试是唯一的出路。 找出哪些函数给你带来问题,然后找出问题出现在函数中的哪个位置,并修复这些部分。 但是,我仍然怀疑单个数学运算(即使重复多次,多次运算)也会导致任何瓶颈。

    Thomas Owens answered 2019-07-07T03:19:45Z

    35 votes

    乘法更快,除法更准确。 如果你的数字不是2的幂,你将失去一些精确度:

    y = x / 3.0;

    y = x * 0.333333; // how many 3's should there be, and how will the compiler round?

    即使你让编译器找出反转常数到完美精度,答案仍然可能不同。

    x = 100.0;

    x / 3.0 == x * (1.0/3.0) // is false in the test I just performed

    速度问题只有在C / C ++或JIT语言中才有意义,即使这样,只有在操作处于瓶颈的循环中时才会如此。

    Mark Ransom answered 2019-07-07T03:20:27Z

    24 votes

    如果您想优化代码但仍然清晰,请尝试以下方法:

    y = x * (1.0 / 2.0);

    编译器应该能够在编译时进行除法,因此您可以在运行时获得乘法。 我希望精度与y = x / 2.0中的精度相同。

    在这可能很重要的情况下,LOT在嵌入式处理器中,其中需要浮点仿真来计算浮点运算。

    Jason S answered 2019-07-07T03:21:06Z

    19 votes

    只是为其他语言添加一些东西" 选项。

    C:因为这只是一个真正没有区别的学术练习,我想我会做出不同的贡献。

    我编译成汇编而没有优化,并查看结果。

    代码:

    int main() {

    volatile int a;

    volatile int b;

    asm("## 5/2\n");

    a = 5;

    a = a / 2;

    asm("## 5*0.5");

    b = 5;

    b = b * 0.5;

    asm("## done");

    return a + b;

    }

    编译为main()

    划分为2:

    movl $5, -4(%ebp)

    movl -4(%ebp), %eax

    movl %eax, %edx

    shrl $31, %edx

    addl %edx, %eax

    sarl %eax

    movl %eax, -4(%ebp)

    和乘以0.5:

    movl $5, -8(%ebp)

    movl -8(%ebp), %eax

    pushl %eax

    fildl (%esp)

    leal 4(%esp), %esp

    fmuls LC0

    fnstcw -10(%ebp)

    movzwl -10(%ebp), %eax

    orw $3072, %ax

    movw %ax, -12(%ebp)

    fldcw -12(%ebp)

    fistpl -16(%ebp)

    fldcw -10(%ebp)

    movl -16(%ebp), %eax

    movl %eax, -8(%ebp)

    但是,当我将这些main()s更改为a + bs(这可能是python可能会做的)时,我得到了这个:

    师:

    flds LC0

    fstl -8(%ebp)

    fldl -8(%ebp)

    flds LC1

    fmul %st, %st(1)

    fxch %st(1)

    fstpl -8(%ebp)

    fxch %st(1)

    乘法:

    fstpl -16(%ebp)

    fldl -16(%ebp)

    fmulp %st, %st(1)

    fstpl -16(%ebp)

    我没有对这些代码进行基准测试,但只是通过检查代码,你可以看到使用整数,除以2比乘以2短。使用双倍,乘法更短,因为编译器使用处理器' s浮点操作码,可能运行得更快(但实际上我不知道),而不是使用它们进行相同的操作。 因此,最终这个答案表明多平面的性能为0.5而除以2则取决于语言的实现及其运行的平台。 最终差异可以忽略不计,除了可读性之外,你几乎从不担心。

    作为旁注,您可以看到我的程序main()返回a + b.当我取消volatile关键字时,您永远不会猜测程序集的外观(不包括程序设置):

    ## 5/2

    ## 5*0.5

    ## done

    movl $5, %eax

    leave

    ret

    它在单个指令中完成了除法,乘法和加法! 显然,如果优化器是任何可敬的,你不必担心这一点。

    对不起,答案太长了。

    Carson Myers answered 2019-07-07T03:23:09Z

    10 votes

    首先,除非您在C或ASSEMBLY工作,否则您可能处于更高级别的语言,其中内存停滞和一般呼叫开销绝对会使乘法和除法之间的差异相形见绌。 所以,在这种情况下,只需选择更好的读数。

    如果您从非常高的级别谈话,那么对于您可能会使用它的任何内容来说,它的速度都会慢得多。 你会在其他答案中看到,人们需要做一百万乘法/除法才能测量两者之间的一些亚毫秒差异。

    从低级别的优化角度来看,如果您仍然感到好奇:

    划分往往具有比乘法更长的管道。 这意味着获得结果需要更长的时间,但如果您可以让处理器忙于处理非依赖性任务,那么它最终不会花费您的成本。

    管道差异的长度完全取决于硬件。 我使用的最后一个硬件类似于FPU乘法的9个周期和FPU除法的50个周期。 听起来很多,但是你会因为记忆失误而失去1000个周期,这样就可以把事情放在眼里。

    一个类比是在观看电视节目时将馅饼放在微波炉中。 你离开电视节目的总时间是将它放入微波炉并将其从微波炉中取出多长时间。 剩下的时间你还在观看电视节目。 因此,如果馅饼需要10分钟来烹饪而不是1分钟,那么它实际上不会消耗你的电视观看时间。

    实际上,如果您要达到关注Multiply和Divide之间差异的程度,您需要了解管道,缓存,分支停顿,无序预测和管道依赖性。 如果这听起来不像你想要回答这个问题,那么正确的答案是忽略两者之间的差异。

    很多(很多)年前,避免分歧绝对是至关重要的,并且总是使用倍数,但当时内存命中的相关性较低,而且分歧要差得多。 这些天我对可读性的评价较高,但如果没有可读性差异,我认为选择倍增是一个好习惯。

    James Podesta answered 2019-07-07T03:24:35Z

    8 votes

    写下哪一个更清楚地表明你的意图。

    在你的程序运行之后,弄清楚什么是慢的,并加快速度。

    不要反过来做。

    Jay Bazuzi answered 2019-07-07T03:25:18Z

    7 votes

    做你需要的一切。 首先考虑一下您的读者,在确定性能问题之前不要担心性能问题。

    让编译器为您执行性能。

    buti-oxa answered 2019-07-07T03:25:55Z

    4 votes

    如果您正在使用整数或非浮点类型,请不要忘记您的位移操作符:<<>>

    int y = 10;

    y = y >> 1;

    Console.WriteLine("value halved: " + y);

    y = y << 1;

    Console.WriteLine("now value doubled: " + y);

    sbeskur answered 2019-07-07T03:26:20Z

    4 votes

    乘法通常更快 - 当然永远不会慢。但是,如果它不是速度关键,请写出最清楚的。

    Dan Hewett answered 2019-07-07T03:26:47Z

    4 votes

    实际上有一个很好的理由,因为一般的经验法则乘法比分裂更快。硬件中的浮点除法可以使用移位和条件减法算法(&#34;长除法&#34;带二进制数)或者 - 更有可能这些天 - 使用像Goldschmidt算法这样的迭代。移位和减法需要每位精度至少一个周期(迭代几乎不可能并行化,因为乘法的移位和相加),并且迭代算法每次迭代至少进行一次乘法。在任何一种情况下,该部门很可能需要更多周期。当然,这并不能解释编译器,数据移动或精度方面的怪癖。但总的来说,如果您在程序的时间敏感部分编写内部循环,则编写0.5 * x或1.0/2.0 * x而不是x / 2.0是合理的做法。 &#34;的迂腐代码是什么,最清楚的&#34;这是完全正确的,但是这三者都具有如此接近的可读性,以至于在这种情况下,迂腐只是迂腐。

    Gene answered 2019-07-07T03:27:21Z

    3 votes

    浮点除法(通常)特别慢,因此虽然浮点乘法也相对较慢,但它可能比浮点除法更快。

    但我更倾向于回答&#34;它并不重要&#34;除非分析表明除法与乘法相比有点瓶颈。 不过,我猜测乘法与除法的选择不会对您的应用产生很大的性能影响。

    mipadi answered 2019-07-07T03:27:59Z

    2 votes

    我一直都知道乘法更有效率。

    Toon Krijthe answered 2019-07-07T03:28:26Z

    2 votes

    当您在汇编或C语言编程时,这变得更加成为一个问题。我认为,对于大多数现代语言来说,这样的优化正在为我完成。

    Seamus answered 2019-07-07T03:28:52Z

    2 votes

    警惕&#34;猜测乘法通常更好,所以当我编码时我会坚持这样做,&#34;

    在这个具体问题的背景下,这里更好的意思是“更快”#34; 哪个不是很有用。

    考虑速度可能是一个严重的错误。 在计算的特定代数形式中存在深刻的错误含义。

    请参见具有错误分析的浮点算法。 请参阅浮点算术和错误分析中的基本问题。

    虽然一些浮点值是精确的,但大多数浮点值是近似值; 他们是一些理想的价值加上一些错误。 每个操作都适用于理想值和误差值。

    最大的问题来自于试图操纵两个几乎相等的数字。 最右边的位(错误位)主导结果。

    >>> for i in range(7):

    ... a=1/(10.0**i)

    ... b=(1/10.0)**i

    ... print i, a, b, a-b

    ...

    0 1.0 1.0 0.0

    1 0.1 0.1 0.0

    2 0.01 0.01 -1.73472347598e-18

    3 0.001 0.001 -2.16840434497e-19

    4 0.0001 0.0001 -1.35525271561e-20

    5 1e-05 1e-05 -1.69406589451e-21

    6 1e-06 1e-06 -4.23516473627e-22

    在此示例中,您可以看到随着值变小,几乎相等的数字之间的差异会在正确答案为零的情况下创建非零结果。

    S.Lott answered 2019-07-07T03:30:08Z

    1 votes

    我已经读过某个地方,乘法在C / C ++中效率更高; 不知道解释语言 - 由于所有其他开销,差异可能微不足道。

    除非它成为一个问题坚持更可维护/可读的东西 - 我讨厌人们告诉我这一点,但它是如此真实。

    Christopher Lightfoot answered 2019-07-07T03:30:41Z

    1 votes

    我会建议乘法一般,因为你不必花费周期来确保你的除数不是0.当然,如果你的除数是常数,那么这并不适用。

    Steve answered 2019-07-07T03:31:06Z

    1 votes

    Java android,在三星GT-S5830上描述

    public void Mutiplication()

    {

    float a = 1.0f;

    for(int i=0; i<1000000; i++)

    {

    a *= 0.5f;

    }

    }

    public void Division()

    {

    float a = 1.0f;

    for(int i=0; i<1000000; i++)

    {

    a /= 2.0f;

    }

    }

    结果?

    Multiplications(): time/call: 1524.375 ms

    Division(): time/call: 1220.003 ms

    除法乘法(!)快20%左右

    PiotrK answered 2019-07-07T03:31:48Z

    1 votes

    与帖子#24(乘法更快)和#30一样 - 但有时它们都很容易理解:

    1*1e-6F;

    1/1e6F;

    〜我发现它们都很容易阅读,并且必须重复数十亿次。 因此,知道乘法通常更快是有用的。

    Chris answered 2019-07-07T03:32:23Z

    1 votes

    有区别,但它依赖于编译器。 首先在vs2003(c ++)上,我对双类型(64位浮点)没有显着差异。 然而,在vs2010上再次运行测试,我发现了一个巨大的差异,乘法更快到4倍。 跟踪此情况,似乎vs2003和vs2010生成不同的fpu代码。

    Pentium 4,2.8 GHz,vs2003:

    乘法:8.09

    分部:7.97

    在Xeon W3530上,vs2003:

    乘法:4.68

    分部:4.64

    在Xeon W3530上,vs2010:

    乘法:5.33

    分部:21.05

    似乎在vs2003中,循环中的除法(因此除数被多次使用)被转换为与逆的乘法。 在vs2010上,此优化不再适用(我想因为两种方法之间的结果略有不同)。 另请注意,只要分子为0.0,cpu就会更快地执行除法。 我不知道芯片中硬连线的精确算法,但也许它取决于数字。

    编辑18-03-2013:对vs2010的观察

    gast128 answered 2019-07-07T03:34:26Z

    1 votes

    这是一个愚蠢有趣的答案:

    x / 2.0不等于x * 0.5

    我们假设你在2008年10月22日写了这个方法。

    double half(double x) => x / 2.0;

    现在,10年后,您了解到可以优化这段代码。 在整个应用程序中,该方法在数百个公式中被引用。 所以你改变了它,并且体验了5%的显着性能提升。

    double half(double x) => x * 0.5;

    改变代码是正确的决定吗? 在数学中,这两个表达式确实是等价的。 在计算机科学中,这并不总是成立。 有关更多详细信息,请阅读最小化精度问题的影响。 如果您的计算值 - 在某个时刻 - 与其他值进行比较,您将更改边缘情况的结果。 例如。:

    double quantize(double x)

    {

    if (half(x) > threshold))

    return 1;

    else

    return -1;

    }

    底线是; 一旦你适应了两者中的任何一个,那么坚持下去!

    l33t answered 2019-07-07T03:35:35Z

    0 votes

    好吧,如果我们假设加/减运算成本为1,那么将成本乘以5,并将成本除以20。

    matma answered 2019-07-07T03:36:05Z

    0 votes

    经过如此漫长而有趣的讨论后,我对此表示了看法:这个问题没有最终答案。 正如有些人指出的那样,它取决于硬件(cf piotrk和gast128)和编译器(cf @ Javier的测试)。 如果速度并不重要,如果您的应用程序不需要实时处理大量数据,您可以选择使用除法清晰度,而如果处理速度或处理器负载是一个问题,乘法可能是最安全的。最后,除非您确切知道应用程序将部署在哪个平台上,否则基准测试毫无意义。 为了清晰代码,单个评论就可以完成工作!

    Jean-François answered 2019-07-07T03:36:35Z

    -2 votes

    从技术上讲,没有除法之类的东西,只有逆元素的乘法。 例如,你永远不会除以2,实际上你乘以0.5。

    &#39;司&#39; - 让我们自己说它存在一秒钟 - 总是更难以乘法,因为它会分裂&#39; x由y首先需要计算值y^{-1}这样y*y^{-1} = 1然后再做乘法x*y^{-1}.如果你已经知道y^{-1}则不计算它从y必须进行优化。

    briantyler answered 2019-07-07T03:37:21Z

    展开全文
  • 在计算机中,乘法运算是一种很重要的运算,有的机器由硬件乘法器直接完成乘法运算,有的机器内没有乘法器,但可以按机器作乘法运算的方法,用软件编程实现。因此,学习乘法运算方法不仅有助于乘法器的设计,也有助于...

    目录

    一、乘法运算

    1、分析笔算乘法

    2、笔算乘法的改进

    3、原码一位乘法

    4、原码两位乘法

    5、补码一位乘法

    6、补码两位乘

    二、除法运算

    1.分析笔算除法

    2、原码除法

    (1)恢复余数法

    (2)加减交替法

    (3)原码加减交替法所需的硬件配置

    (4)原码加减交替除法控制流程

    3、补码除法

    (1)补码加减交替法运算规则

    (2)补码加减交替法所需的硬件配置

    (3)补码加减交替法的控制流程


    一、乘法运算

    在计算机中,乘法运算是一种很重要的运算,有的机器由硬件乘法器直接完成乘法运算,有的机器内没有乘法器,但可以按机器作乘法运算的方法,用软件编程实现。因此,学习乘法运算方法不仅有助于乘法器的设计,也有助于乘法编程。

    下面从分析笔算乘法入手,介绍机器中用到的几种乘法运算方法。

    1、分析笔算乘法

    设A=0.1101,B=0.1011,求A×B。

    笔算乘法时乘积的符号由两数符号心算而得:正正得正;其数值部分的运算如下:

    所以  A×B=+0.10001111

    可见,这里包含着被乘数4的多次左移,以及四个位积的相加运算。

    若计算机完全模仿笔算乘法步骤,将会有两大困难:

    • 其一,将四个位积一次相加,机器难以实现;
    • 其二,乘积位数增长了一倍,这将造成器材的浪费和运算时间的增加。

    为此,对笔算乘法做些改进。

    2、笔算乘法的改进

    将A•B =  A•0.1011

       = 0.1A+0.001•A+0.0001•A

       = 0.1A+0.00•A+0.001(A+0.1A)

       = 0.1A+0.01[0•A+0.1(A+0.1A)]

       = 0.1{A+0.1[0•A+0.1(A+0.1A)]}

       = 2^-1{A+2^-1 [0•A+2^-1 (A+2^-1A)]}

       = 2^-1{A+2^-1 [0•A+2^-1 (A+2^-1(A+0))]}

    由上式可见,两数相乘的过程,可视作加法和移位(乘2^-1相当于做一位右移)两种运算,这对计算机来说是非常容易实现的。

    从初始值为0开始,对上式作分步运算,则:

    • 第一步:被乘数加零                 A+0=0.1101+0.0000=0.1101
    • 第二步:右移一位,得新的部分积   2^-1 (A+0)=0.01101
    • 第三步:被乘数加部分积                       A+2^-1(A+0)=0.1101+0.01101=1.00111
    • 第四步:右移一位,得新的部分积         2^-1 A+2^-1 (A+0)=0.100111
    • 第五步:0•A +2^-1 [A+2^-1 (A+0)] =0.100111
    • 第六步:2^-1{0•A+2^-1 [A+2^-1 (A+0)]}=0.0100111
    • 第七步:A+2^-1{0•A+2^-1 [A+2^-1 (A+0)]}=1.0001111
    • 第八步:2^-1 {A+2^-1[0•A+2^-1 (A+2^-1 (A+0))]}=0.10001111

    上述运算过程可归纳为:

    乘法运算可用移位和加法来实现,当两个四位数相乘,总共需做四次加法和四次移位。

    ②由乘数的末位值确定被乘数是否与原部分积相加,然后右移一位,形成新的部分积;同时,乘数也右移一位,由次低位作新的末位,空出最高位放部分积的最低位。

    ③每次做加法时,被乘数仅仅与原部分积的高位相加,其低位被移至乘数所空出的高位位置。

    计算机很容易实现这种运算规则。用一个寄存器存放被乘数,一个寄存器存放乘积的高位,又用一个寄存器存放乘数及乘积的低位,再配上加法器及其他相应电路,就可组成乘法器。又因加法只在部分积的高位进行,故不但节省了器材,而且还缩短了运算时间。

    3、原码一位乘法

    由于原码表示与真值极为相似,只差一个符号,而乘积的符号又可通过两数符号的逻辑异或求得,因此,上述讨论的结果可以直接用于原码一位乘,只需加上符号位处理即可。

    上图是一个32位乘法器的结构框图,其中32位被乘数放在R2中,运算开始时32位乘数放在R1中,运算结束时64位乘积的高位放在R0中,低位放在R1中,R0和R1串联移位。

    完成这个定点原码一位乘法的运算规则可以用如下图所示的逻辑流程图表示。

    在该乘法过程中,每次操作是根据乘数的一位进行操作,对于32位数的乘法,需要循环32次完成一个乘法操作,因此称为一位乘法。

    例:用原码的乘法方法进行2×3的四位乘法。

    解:在乘法开始之前,R0和R1中的初始值为0000和0011,R2中的值为0010。

    在乘法的第一个循环中,判断R1的最低位为1,所以进入步骤1a,将R0的值加上R2的值,结果0010送人R0,然后进入第二步,将R0和R1右移一位,R0、Rl的结果为0001 0001,见下表的循环1,表中黑体字的数据位是乘法过程中判断的R1最低位。

    第二个循环过程中,判断R1的最低位为1,仍进入步骤la,加0010,结果为0011,然后在第二步中将R0和R1右移一位,结果为0001 1000,见下表的循环2。

    第三次循环中,因R1的最低位为0,进入步骤lb,R0不变,第二步移位后结果为00001100,见下表的循环3。

    第四次循环时,仍因R1最低位为0,只作移位,结果为00000110,这就是乘法的结果6,见下表的循环4。

    4、原码两位乘法

    原码两位乘与原码一位乘一样,符号位的运算和数值部分是分开进行的,但原码两位乘是用两位乘数的状态来决定新的部分积如何形成,因此可提高运算速度

    两位乘数共有4种状态,对应这4种状态可得下表。

    表中倍被乘数可通过将被乘数左移一位实现,而3倍被乘数的获得可以分两步来完成,利用3=4-1,第一步先完成减1倍被乘数的操作,第二步完成加4倍被乘数的操作。而加4倍被乘数的操作实际上是由比“11”高的两位乘数代替完成的,可以看作是在高两位乘数上加“1”。这个“1”可暂时存在Cj触发器中。机器完成置“1” Cj即意味着对高两位乘数加1,也即要求高两位乘数代替本两位乘数“11”来完成加4倍被乘数的操作。

    虽然两位乘法可提高乘法速度,但它仍基于重复相加和移位的思想,而且随着乘数位数的增加,重复次数增多,仍然影响乘法速度的进一步提高。采用并行阵列乘法器可大大提高乘法速度。

    原码乘法实现比较容易,但由于机器都采用补码作加减运算,倘若做乘法前再将补码转换成原码,相乘之后又要将负积的原码变为补码形式,这样增添了许多操作步骤,反而使运算复杂。为此,有不少机器直接用补码相乘,机器里配置实现补码乘法的乘法器,避免了码制的转换,提高了机器效率。

    5、补码一位乘法

    一种比较好的带符号数乘法的方法是布斯(Booth)算法。它采用相加和相减的操作计算补码数据的乘积。

    Booth算法对乘数从低位开始判断,根据两个数据位的情况决定进行加法、减法还是仅仅移位操作

    判断的两个数据位为当前位及其右边的位(初始时需要增加一个辅助位0),移位操作是向右移动。

    比如:

    • 第一次判断被乘数0110中的最低位0以及右边的位(辅助位0),得00;所以只进行移位操作;
    • 第二次判断0110中的低两位,得10,所以作减法操作并移位,这个减法操作相当于减去2a的值;
    • 第三次判断被乘数的中间两位,得11,于是只作移位操作;
    • 第四次判断0110中的最高两位,得01,于是作加法操作和移位,这个加法相当于加上8a的值,因为a的值已经左移了三次。

    一般而言,设y=y0,y1y2…yn为被乘数,x为乘数,yi是a中的第i位(当前位)。根据yj与yi+1的值,Booth算法表示如下表所示,其操作流程如下图所示。在Booth算法中,操作的方式取决于表达式(yi+1-yi)的值,这个表达式的值所代表的操作为:

    • 0    无操作
    • +1    加x
    • -1    减x

    Booth算法操作表示

    实现32位Booth乘法算法的流程图

    乘法过程中,被乘数相对于乘积的左移操作可表示为乘以2,每次循环中的运算可表示为对于x(y(i+1)-yi)2^(31-i)项的加法运算(i=31,30,…,1,0)。这样,Booth算法所计算的结果  可表示为:

    例:用Booth算法计算2×(-3)。

    解:[2]补=0010,  [-3]补=1101,在乘法开始之前,R0和R1中的初始值为0000和1101,R2中的值为0010。

    在乘法的第一个循环中,判断R1的最低位和辅助位为10,所以进入步骤1c,将R0的值减去R2的值,结果1110送人R0,然后进人第二步,将R0和Rl右移一位,R0和R1的结果为11110110,辅助位为1。

    在第二个循环中,首先判断Rl的最低位和辅助位为01,所以进入步骤1b,作加法,R0+R2=1111+0010,结果0001送入R0,这时R0R1的内容为0001 0110,在第二步右移后变为0000 1011,辅助位为0。

    在第三次循环中,判断位为10,进入步骤lc,R0减去R2,结果1110送入R0,R1不变;步骤2移位后R0和R1的内容为1111 01011,辅助位为1。

    第四次循环时,因两个判断位为11,所以不作加减运算,向右移位后的结果为1111 1010,这就是运算结果(-6)。

    这个乘法的过程描述如下表所示,表中乘积一栏表示的是R0、R1的内容以及一个辅助位P,黑体字表示对两个判断位的判断。

    用Booth补码一位乘法计算2 ×(-3)的过程

    6、补码两位乘

    补码两位乘运算规则是根据补码一位乘的规则,把比较yiy(i+1)的状态应执行的操作和比较y(i-1)yi 的状态应执行的操作合并成一步,便可得出补码两位乘的运算方法。

    补码两位乘法运算规则如下

    由上表可见,操作中出现加2[x]补和加2[-x]补,故除右移两位的操作外,还有被乘数左移一位的操作;而加2[x]补和加2[-x]补,都可能因溢出而侵占双符号位,故部分积和被乘数采用三位符号位。

    例:[x]补=0.0101,[y]补=1.0101 求: [x• y]补。

    解:求解过程如下表所示。其中乘数取两位符号位即11.0101,[-x]补=1.1011取三符号位为111.1011。

    故[x• y]补=1.11001001

    可见,与补码一位乘相比,补码两位乘的部分积多取一位符号位(共3位),乘数也多取一位符号位(共2位),这是由于乘数每次右移2位,且用3位判断,故采用双符号位更便于硬件实现。可见,当乘数数值位为偶数时,乘数取2位符号位,共需作n/2次移位,最多作n/2+1次加法,最后一步不移位;当n为奇数时,可补0变为偶数位,以简化逻辑操作。也可对乘数取1位符号位,此时共作n/2+1次加法和n/2+1次移位(最后一步移一位)。

    对于整数补码乘法,其过程与小数乘法完全相同。为了区别于小数乘法,在书写上可将符号位和数值位中间的“.”改为“,”即可。

    https://wenku.baidu.com/view/22b2b63231126edb6f1a10bf.html

    二、除法运算

    1.分析笔算除法

    以小数为例,设 x=-0.1011,y=0.1101,求x/y

    笔算除法时,商的符号心算而得:负正得负;其数值部分的运算如下面竖式。

    所以商x/y=0.1101,余数=-0.00000111

    其特点可归纳如下:

    每次上商都是由心算来比较余数(被除数)和除数的大小,确定商为1还是0。

    每做一次减法,总是保持余数不动,低位补0,再减去右移后的除数。

    商符单独处理。如果将上述规则完全照搬到计算机内,实现起来有一定困难,主要问题是:

      a.机器不能“心算”上商,必须通过比较被除数(或余数)和除数绝对值的大小来确定商值,即|x|-|y|,若差为正(够减)上商1,差为负(不够减)上商0。

      b.按照每次减法总是保持余数不动低位补0,再减去右移后的除数这一规则,则要求加法器的位数必须为除数的两倍。仔细分析发现,右移除数可以用左移余数的办法代替,其运算结果是一样的,但对线路结构更有利。不过此刻所得到的余数不是真正的余数,只有将它乘上2^-n才是真正的余数。

      c.笔算求商时是从高位向低位逐位求的,而要求机器把每位商直接写到寄存器的不同位也是不可取的。计算机可将每一位商直接写到寄存器的最低位,并把原来的部分商左移一位。

    综上所述便可得原码除法运算规则。

    2、原码除法

    原码除法和原码乘法一样,符号位是单独处理的。以小数为例:

    式中为x的绝对值,记作x*

    为y的绝对值,记作y*

    即商符由两数符号位“异或”运算求得,商值由两数绝对值相除(x*/y*)求得。

    小数定点除法对被除数和除数有一定的约束,即必须满足下列条件:

       0<|被除数| ≤ |除数|

    实现除法运算时,还应避免除数为0或被除数为0。前者结果为无限大,不能用机器的有限位数表示;后者结果总是0,这个除法操作等于白做,浪费了机器时间。至于商的位数一般与操作数的位数相同。

    原码除法中由于对余数的处理不同,又可分为恢复余数法和不恢复余数法(加减交替法)两种。

    (1)恢复余数法

    恢复余数法的特点是:当余数为负时,需加上除数,将其恢复成原来的余数。

    由上所述,商值的确定是通过比较被除数和除数的绝对值大小,即x*-y*实现的, 而计算机内只设加法器, 故需将x*-y*操作变为[x*]补+[-y*]补的操作。

    例:已知:x=-0.1011,y=-0.1101,求:[x÷y]原

    解:由x*=0.1011,[x]原=1.1011

    y*=0.1101,[-y]补=1.0011,[y]原=1.1101

    商值的求解过程如下:

    故商值为0.1101

    商的符号位为

    由此可见,共上商5次,第一次上的商在商的整数位上,这对小数除法而言,可用它作溢出判断。即当该位为“1”时,表示此除法为溢出,不能进行,应由程序进行处理;当该位为“0”时,说明除法合法,可以进行。

    在恢复余数法中,每当余数为负时,都需恢复余数,这变延长了机器除法的时间,操作也很不规则,对线路结构不利。加减交替法可克服这些缺点。

    (2)加减交替法

    加减交替法又称不恢复余数法,可以认为它是恢复余数法的一种改进算法。

    分析原码恢复余数法得知:

    • 当余数Ri>0时,可上商“1”,再对Ri左移一位后减除数,即2Ri-y*。
    • 当余数Ri>0时,可上商“0”,然后再做Ri+y*,即完成恢复余数的运算,再做2(Ri+y*)-y*,也即2Ri+y*。

    可见,原码恢复余数法可归纳为:

    • 当余数Ri>0时,商上“1”,做2Ri-y*的运算;
    • 当余数Ri<0时,商上“0”,做2Ri+y*的运算。

    这里已看不出余数的恢复问题了,而只是做加y*或减y*,因此,一般把它叫做加减交替法或不恢复余数法。

    例:已知:x=-0.1011,y=-0.1101,求:[x÷ y]原

    解:[x]原=1.1011, x*=0.1011

    [y]原=0.1101,y*=0.1101,[-y*]补=1.0011

    商值的求解过程如下表所示:

    商的符号位为

    所以

    分析此例可见,n位小数的除法共上商n+1次,第一次商用来判断是否溢出。

    倘若比例因子选择恰当,除数结果不溢出,则第一次商肯定是0。如果省去这位商,只需上商n次即可,此时除法运算一开始应将被除数左移一位减去除数,然后再根据余数上商。

    (3)原码加减交替法所需的硬件配置

    下图是实现原码加减交替除法运算的基本硬件配置框图

    图中A、X、Q均为n+1位寄存器,其中A存放被除数的原码,X存放除数的原码。

    移位和加控制逻辑受Q的末位Qn控制。(Qn=1作减法,Qn=0作加法),计数器C用于控制逐位相除的次数n,GD为除法标记,V为溢出标记,S为商符。

    (4)原码加减交替除法控制流程

    下图为原码加减交替除法控制流程图

    除法开始前,Q寄存器被清0,准备接收商,被除数的原码放在A中,除数的原码放在X中,计数器C中存放除数的位数n。

    除法开始后,首先通过异或运算求出商符,并存于S。

    接着将被除数和除数变为绝对值,然后开始用第一次上商判断是否溢出。

    若溢出,则置溢出标记V为1,停止运算,进行中断处理,重新选择比例因子:若无溢出,则先上商,接着A、Q同时左移一位,然后再根据上一次商值的状态,决定是加还是减除数,这样重复n次后,再上最后一次商(共上商n+1次),即得运算结果。

    对于整数除法,要求满足以下条件:

      0 < |除数| ≤ |被除数|

    因为这样才能得到整数商。通常在做整数除法前,先要对这个条件进行判断,若不满足上述条件,机器发出出错信号,程序要重新设定比例因子。

    上述讨论的小数除法完全适用于整数除法,只是整数除法的被除数位数可以是除数的两倍,且要求被除数的高M位要比除数(n位)小,否则即为溢出。

    如果被除数和除数的位数都是单字长,则要在被除数前面加上一个字的0,从而扩展成双倍字长再进行运算。

    3、补码除法

    与补码乘法类似,也可以用补码完成除法操作。补码除法也分恢复余数法和加减交替法,后者用得较多,在此只讨论加减交替法。

    (1)补码加减交替法运算规则

    补码除法其符号位和数值部分是一起参加运算的,因此在算法上不像原码除法那样直观,主要需解决三个问题:

    • 第一,如何确定商值
    • 第二,如何形成商符
    • 第三,如何获得新的余数

    ① 商值的确定

    欲确定商值,必须先比较被除数和除数的大小,然后才能求得商值。

    a. 比较被除数(余数)和除数的大小

    补码除法的操作数均为补码,其符号又是任意的,因此要比较被除数[x]补和除数[y]补的大小就不能简单地用[x]补减去[y]补。实质上比较[x]补和[y]补的大小就是比较它们所对应的绝对值的大小。同样在求商的过程中,比较余数[Ri]补与除数[y]补的大小,也是比较它们所对应的绝对值。这种比较的算法可归纳为以下两点:

    • 第一,当被除数与除数同号时,做减法,若得到的余数与除数同号,表示“够减”,否则表示“不够减”。
    • 第二,当被除数与除数异号时,做加法,若得到的余数与除数异号,表示“够减”,否则表示“不够减”。

    此算法如下表所示

    b.商值的确定

    补码除法的商也是用补码表示的,如果我们约定商的末位用“恒置1”的舍入规则,那么除末位商外,其余各位的商值对正商和负商而言,上商规则是不同的。因为在负商的情况下,除末位商以外,其余任何一位的商与真值都正好相反。因此,上商的算法可归纳为以下两点:

    • 第一,如果[x]补与[y]补同号,商为正,则“够减”时上商“1”。“不够减”时上商“0”(按原码规则上商)。
    • 第二,如果[x]补与[y]补异号,商为负,则“够减”时上商“0”,“不够减”时上商“1”(按反码规则上商)。

    结合比较规则与上商规则,使可得商值的确定办法,如下表所示

    进一步简化,商值可直接由下表确定

    ② 商符的形成

    在补码除法中,商符是在求商的过程中自动形成的。

    在小数定点除法中,被除数的绝对值必须小于除数的绝对值,否则商大于1而溢出。

    因此,当[x]补与[y]补同号时,[x]补-[y]补所得的余数[R0]补与[y]补异号,商上“0”,恰好与商的符号(正)一致;当[x]补与[y]补异号时,[x]补+[y]补所得的余数[R0]补与[y]补同号,商上“1”,这也与商的符号(负)一致。

    可见,商符是在求商值过程中自动形成的。

    此外,商的符号还可用来判断商是否溢出。

    例如,当[x]补与[y]补同号时,若[R0]补与[y]补同号,上商“l”,即溢出。当[x]补与[y]补异号时,若[R0]补与[y]补异号,上商“0”,即溢出。

    当然,对于小数补码运算,商等于“-1”应该是允许的,但这需要特殊处理,为简化问题,这里不予考虑。

    ③ 新余数[R(i+1)]补的获得

    新余数[R(i+1)]补的获得方法与原码加减交替法极相似,其算法规则为:

    • 当[R0]补与[y]补同号时,商上“1”,新余数 [R(i+1)]补 = 2[Ri]补 - [y]补 = 2[Ri]补 + [-y]补
    • 当[R0]补与[y]补异号时,商上“0”,新余数 [R(i+1)]补 = 2[Ri]补 + [y]补

    将此法列于下表:

    如果对商的精度没有特殊要求,一般可采用“末位恒置1”法,这种方法操作简单,易于实现,而且最大误差仅为2^(-n)。

    例:已知:x=-0.1001, y=+0.1101 求: [x÷y]补

    解:[x]补=1.0111,[y]补=0.1101,[-y]补=1.0011

    运算过程如下:

    所以[x÷y]补 = 1.0101

    (2)补码加减交替法所需的硬件配置

    补码加减交替法所需的硬件配置基本上与原码加减交替法所需的硬件配置相似。

    (3)补码加减交替法的控制流程

    除法开始前,Q寄存器被清0,准备接收商,被除数的补码在A中,除数的补码在x中,计数器C中存放除数的位数M。

    除法开始后,首先根据两操作数的符号确定是作加法还是减法,加(或减)操作后,即上第一次商(商符),然后A、Q同时左移一位,再根据商值的状态决定加或减除数,这样重复”次后,再上一次末位商“1”(恒置“1”法),即得运算结果。

    补充说明几点:

    1. 图中未画出补码除法溢出判断的内容;
    2. 按流程图所示,多作一次加(或减)法,其实末位恒置“1”前,只需移位不必作加(或减)法;
    3. 与原码除一样,图中均未指出对0进行检测,实际上在除法运算前,先检测被除数和除数是否为0,若被除数为0,结果即为0;若除数为0,结果为无穷大,这两种情况都无需继续作除法运算;
    4. 为了节省时间,上商和移位操作可以同时进行。
    展开全文
  • 如果是,是否存在可用于决定使用哪个转换因子的转换因子,因为在一次float乘法的同时可以完成多少int个除法?编辑:我认为评论清楚表明浮点数学会慢一点,但问题是,多少? 如果我需要用$ N $ int除法替换每个float...

    如果必须计算给定int值的一小部分,请说:

    int j = 78;

    int i = 5* j / 4;

    这比做的更快:

    int i = 1.25*j; // ?

    如果是,是否存在可用于决定使用哪个转换因子的转换因子,因为在一次float乘法的同时可以完成多少int个除法?

    编辑:我认为评论清楚表明浮点数学会慢一点,但问题是,多少? 如果我需要用$ N $ int除法替换每个float乘法,那么$ N $将不再值得吗?

    你有基准吗?

    这些数字中有多少是动态的?

    @KerrekSB指的是编译器为您优化所有这些。因此,为什么基准测试很重要。

    @KerrekSB - 所有数字都是动态的。这个例子只是一个例子,实际上这些都是动态的。

    我会说如果你有三个整数a,b和c,你想要计算a * b / c,那么你应该写int compute(int a, int b, int c) { return a * b / c; }。我怀疑你能做得更好。

    这似乎是过早优化,还要注意1.25文字实际上是double,而不是float。

    您展示的两种替代方案可能产生不同的结果。首先根据所需结果进行选择,然后根据性能进行选择。

    是否正确舍入结果值可能的问题?

    我也看不到你希望实现的目标。如果所有三个输入都是动态的,那么你最多可以将浮点乘数计算为static_cast(a) / static_cast(c),那么你需要将b转换为浮点,乘以,然后使用C ++舍入,强制舍入,全部和任何一个这不可能比两个整数运算更快。

    你也可以进行整数移位和加法而不是乘法(取决于你的硬件有什么)。使用C和编译器有转换开销等,你不会保持固定点。但答案是不确定的,你只需要测试它......

    你确定你的程序的性能瓶颈是这个操作吗? (我敢打赌它不是。)测量它,然后优化瓶颈。

    @pts - 当这是唯一的操作,并且你重复它10 ^ 7次,这是一个瓶颈。

    你的前提实际上有些缺陷。如果您能够在5/4和1.25之间切换,则不可能使所有数字都是动态的。如果分子和分母不是编译时常数,你怎么知道乘以1.25? (没有实际进行你试图避免的分裂)

    基本算术性能无关紧要我不知道为什么你关心优化这个。你打算在烤面包机里运行这个代码吗?

    只是为了清除事物,在单个操作中在CPU级别执行乘法,并且除法是最昂贵的CPU基本操作之一。是否使用多个操作而不是仅包含一个除法,即使您只使用整数,它也会更快?我真诚地怀疑它。

    你已经说过所有的价值都是动态的,这会产生不同。对于特定值5 * j / 4,整数运算将会非常快,因为最糟糕的情况是编译器将它们优化为两个班次和一个加法,加上一些搞乱来应对j的可能性是否定的。如果CPU可以做得更好(单周期整数乘法或其他),那么编译器通常会知道它。当您编译一大类CPU(例如,生成最低公分母ARM代码)时,编译器优化此类事物的能力的限制基本上就会出现,编译器对此并不太了解硬件,因此不能总是做出好的选择。

    我想如果a和b固定一段时间(但在编译时不知道),则可能是计算k = double(a) / b一次然后int(k * x)对于许多不同的x值,可能是对于x的许多不同值,比计算a * x / b更快。我不会指望它。

    如果所有值每次都变化,那么计算1.25的浮点除法,接着是浮点乘法,似乎不会比整数乘法后跟整数除法更快。但你永远不知道,测试它。

    在现代处理器上为此提供简单的相对时序是不可能的,它实际上很大程度上取决于周围的代码。代码中的主要成本通常不是"实际"操作:它是"不可见"的东西,比如指令管道停止依赖,或者将寄存器溢出到堆栈或函数调用开销。是否可以内联执行此功能的功能可能比功能实际执行的功能更容易产生差异。就性能的确定性陈述而言,您基本上可以测试实际代码或关闭。但是,如果你的值以整数开始,那么对它们进行整数运算将比转换为double并执行类似数量的double运算更快。

    不可能脱离背景地回答这个问题。另外,5*j/4通常不会产生与(int) (1.25*j)相同的结果,这是由于整数和浮点算法的属性,包括舍入和溢出。

    如果你的程序主要执行整数运算,那么j到浮点的转换,乘以1.25,并且转换回整数可能是免费的,因为它使用了没有其他参与的浮点单元。

    或者,在某些处理器上,操作系统可能会将浮点状态标记为无效,因此第一次进程使用它时,有一个例外,操作系统会保存浮点寄存器(包含来自另一个的值)进程),恢复或初始化进程的寄存器,并从异常中返回。相对于正常的指令执行,这将花费大量时间。

    答案还取决于程序正在执行的特定处理器模型的特性,以及操作系统,编译器如何将源转换为汇编,甚至可能取决于系统上的其他进程正在执行的操作。

    此外,5*j/4和(int) (1.25*j)之间的性能差异通常太小而不能在程序中引人注意,除非它或类似的操作重复很多次。 (并且,如果它们是,那么对代码进行矢量化可能会带来巨大的好处,也就是说,使用许多现代处理器的单指令多数据[SIMD]功能可以同时执行多个操作。)

    对于您的情况,5*j/4将比1.25*j快得多,因为通过右移可以轻松地除以2的幂,并且5*j可以通过某些体系结构(例如LEA)上的单个指令来完成。支持ARM的x86或ADD。大多数其他指令最多需要2条指令,如j + j >> 2,但这些指令可能仍然比浮点乘法更快。此外,通过执行int i = 1.25*j,您需要在double和int之间进行2次转换,以及2次跨域移动,这可能非常昂贵(这就是为什么有不同的SSE或AVX指令执行完全相同的操作,只是在不同的域)。使用int multiply / divide也允许编译器通过常数优化除法

    对于其他情况,当分数不能用浮点表示时(比如3*j/10)那么使用int multiply / divide会更正确(因为0.3在二进制浮点中不完全是0.3),并且最可能更快(因为编译器可以通过将其转换为乘法乘法的乘法来优化除以常数。看到

    将数字除以3而不使用*,/,+, - ,%运算符

    使用位移除以10?

    不使用%和/运算符的5的可分性

    对于i和j属于浮点类型的情况,乘以另一个浮点值可能会更快。因为在float和int域之间移动值需要时间,并且int和float之间的转换也需要时间,如上所述

    一个重要的区别是,如果j太大,5*j/4将溢出,但1.25*j不会

    也就是说,对于"更快"和"速度更快"的问题,没有一般性的答案,因为它取决于特定的架构和特定的环境。您必须在系统上进行测量并做出决定。但是如果表达式重复执行很多值,那么就该转到SIMD了

    也可以看看

    为什么int * float比int / int快?

    我应该使用乘法还是除法?

    浮点除法与浮点乘法

    展开全文
  • 关于内核中的乘法除法。作者:heziq 发布于:2015-5-6 22:02前几天一直在看wowo的时间子系统,一直在思索mult和shift变量,为什么mult要尽量大,shift尽量小。这是由c语言的整数算术运算决定的。cyn* mult > ...

    关于内核中的乘法和除法。

    作者:heziq 发布于:2015-5-6 22:02

    前几天一直在看wowo的时间子系统,一直在思索mult和shift变量,为什么mult要尽量大,shift尽量小。这是由c语言的整数算术运算决定的。

    cyn* mult > shift  在不考虑溢出的情况下,cyn * mult没有误差,右移shift有误差,损失小数。

    但是如果cyn > shift * mult 在不考虑溢出的情况下,误差就会被放大。

    10* 12 / 8 = 15

    10 / 8 * 12 = 12

    10 除以 8 = 1, 舍弃0.25 , 0.25 * 12 = 3. 可以看出乘法部分的误差被夸大12倍。

    mult / shift 的比值越大越好,计算的值越精确。shift如果是1,就没有误差,如果shift是10,那么就只能精确到十位。

    表达不好哈,不善于利用数学公式证明。我说的都是整数运算,不考虑浮点数。

    总结两点:

    内核中做运算

    1,尽量做加减法,少做乘除法,尽量用移位做乘除法。这样运算速度快。

    2,做乘除法的时候,先算乘法,最后做除法,乘法的时候注意溢出。

    3,在特殊的情况下,被除数和除数的比值要尽量大,这样计算误差才会小。

    c6a6308114f401be7df747ae46f2b4db.png

    评论:

    2015-05-10 14:28

    GOOD

    发表评论:

    昵称

    邮件地址 (选填)

    个人主页 (选填)

    d4e3789769c8ad44c7e403863bfc3822.png

    展开全文
  • 除法。1.乘法。最简单的A*B,用C语言for循环for(int i=0;i这个是最容易想到的,现在用移位来实现,效率要高一点。例子1.计算A*17法1:A=A<<4+A;//移位一次相当于*2法2:模拟二进制乘法手动运算,适合大整数的...
  • 乘法逆元(除法取模)

    2021-03-10 08:24:52
    当我们要求(a / b) mod p的,且 a 很大,无法直接求得a / b的时,我们就要用到乘法逆元。满足 b * k ≡ 1 (mod p) 的 k 的就是 b 关于 p 的乘法逆元。我们可以通过求 b 关于 p 的乘法逆元 k,将 a 乘上 k 再模...
  • 如果是,是否存在可用于决定使用哪个转换因子的转换因子,因为可以在同一时间内进行多次int除法一次浮点乘法?编辑:我认为评论清楚表明浮点数学会慢一点,但问题是,多少?如果我需要将每个浮点乘法替换为$N $int ...
  • 二、多项式除法 更为一般性的推导,p(X)为被除式,q(X)为商式,r(X)为余式。不妨假设gn-k=1。 若被除式p(X)中Xn-k的系数为1,此时q(X)=1;r(X)=p(X)-g(X)=p(X)+g(X) 若被除式p(X)中Xn-k的系数为0,此时q(X)=...
  • 这是力扣上的一道题目,难度为中等,两数相除:给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法除法和 mod 运算符。
  • js在处理小数的乘除法的时候有一个bug,解决的方法可以是:将小数变为整数来处理。以上的计算可以改为:12.32 * 100 * 7 /100得出的结果是:86.24,正确。另外再计算一下:8.80 * 100 * 12 / 100结果:105....
  • 今天抠一抠细节,记录一下Python在乘除法中的精度问题 1.除法计算 1.1 一般情况下的除法 dived = 20 div = 7 r = dived / div print(r) # 运算结果 # result = 2.857142857142857 1.2 获取小数点后100位的精度...
  • 接下来我将演示大整数的加法、乘法除法操作。附:不考虑负数1、大整数加法思路:我们将两个数进行逆序转换,然后按位进行相加,将相加的结果进行与10相除,商为进位,余数为当前位要保留的数。//大整数加法...
  • 快速立即除法乘法实现(通用算法)原创:HAM这里我们要讲的是如何使用整数乘法来完成除数为常数的整数除法运算,我们假定都是无符号操作,并且运算在Intel 32bit x86 CPU上。在整数除法操作后,我们取的都是商和余数...
  • PAGE 2成绩:成绩:课程设计报告课程名称:计算机组成原理课程设计实验项目:用微指令实现乘法除法的程序姓 名:专 业:计算机科学与技术班 级:计算机14-6班学 号:计算机科学与技术学院实验教学中心2016年 9 月 ...
  • 在Excel中,乘法运算可以是乘积函数或星号*,但它们是不同的。乘积函数不仅使用单个作为参数,而且还使用数组和对单元格的引用。例如,要计算A1到A6中所有的乘积,您不需要一个个地编写它们,只需编写A1:A6;...
  • 最终看到的结果,除法被编译成了idiv,右移被编译成了ishr。就是说并没有优化。(如果是常数运算会直接在编译字节码时常量折叠,此处就不考虑了) 代码的测试结果也印证了这一点: 1 2 3 4 5 6 long a1=System....
  • js在处理小数的乘除法的时候有一个bug,解决的方法可以是:将小数变为整数来处理。以上的计算可以改为:12.32 * 100 * 7 /100得出的结果是:86.24,正确。另外再计算一下:8.80 * 100 * 12 / 100结果:105....
  • 余数*10加上下一位,即 实际除法运算 C.push_back(r/b) 即实际除法,除几商几 r %=b 求余数 r模等于除数即得到余数,如 1%4 = 1 reverse(C.begin(),C.end()) 该例中无区别, 原因为for循环从A.size()-1开始 #...
  • javascript的小数点乘法除法实例导语:想要学好Java语言,必不可少的就是它的四则运算,特别是乘除法。下面的是百分网小编为大家搜集的javascript的小数点乘法除法实例,希望可以帮到你。一、用js计算12.32 * 7 结果...
  • 目录 一、前言 二、高精度乘法; 2.1、模板: ...三、高精度除法;... 很高兴看见您来读我的博客,说来我们上次还在...这次小夏会为您带来高精度乘法除法的模板,以此补全高精度模板的系列; 值得一提的是,本次...
  • 【简答题】任意输入两个数,完成加法、减法、乘法除法运算!(加减乘除运算分别定义四个方法,需要考虑除数不能为0的情况!)【简答题】C语言数据的基本类型有哪些【简答题】编写一个程序实现累加程序【简答题】代码演示...
  • 二、课程设计的任务针对COP2000实验仪,从详细了解该模型机的指令/微指令系统入手,以实现乘法除法运算功能为应用目标,在COP2000的集成开发环境下,设计全新的指令系统并编写对应的微程序;之后编写实现乘法除法的...
  • 除法器 模拟实验 文章目录WinMIPS64 32位乘法器&除法器 模拟实验一、实验内容二、实验环境三、实验步骤1. 忽略溢出的乘法器2. 溢出提示的乘法器3. 基础除法器的实现4. 乘除中正负号的处理四、实验总结 一、实验...
  • FPGA浮点转定点运算、除法乘法运算以及运算误差分析 FPGA在常规运算时不能进行浮点运算,只能进行定点整型运算,在处理数据的小数乘加运算和除法运算时FPGA一般是无能为力的,其中一种常用的处理方法就是数据进行...
  • cordic算法是一种易于硬件实现的求基本函数的算法,将复杂运算转化为加法、减法和移位操作的组合,避免硬件上不易实现的复杂运算,比如除法,开方等,另外可以避免查找表方法带来的占用较多存储资源的问题。...
  • 一般情况下,这类MCU没有硬件乘法除法指令,在程序必须使用乘除法运算时,如果单纯依靠编译器调用内部函数库来实现,常常会有代码量偏大、执行效率偏低的缺点。上海晟矽微电子推出的MC30、MC32系列MCU,采用了RISC...
  • 1.可控加法/减法(CAS)单元和阵列乘法器非常相似,阵列式除法器也是一种并行运算部件,采用大规模集成电路制造。与早期的串行除法器相比,阵列除法器不仅所需的控制线路少,而且能提供令人满意的高速运算速度。阵列...
  • excel除法结果怎么出现英文字母所说的“英文字母”是否为:#DIV/0! ?,它表示公式中出现了以0为除数的错误。Excel函数的乘和除是哪个英文啊,我都要晕死了?直接用/ *excel中求除法的函数名称是什么一、在EXCEL电子...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 76,582
精华内容 30,632
关键字:

值是乘法还是除法