Divide and Get Remainder at the same time?

后端 未结 9 1122
不知归路
不知归路 2020-12-15 02:37

Apparently, x86 (and probably a lot of other instruction sets) put both the quotient and the remainder of a divide operation in separate registers.

Now, we can proba

相关标签:
9条回答
  • 2020-12-15 03:01

    In Java (since 1.5) the class BigDecimal has the operation divideAndRemainder returning an array of 2 elements with the result and de remainder of the division.

    BigDecimal bDecimal = ...
    BigDecimal[] result = bDecimal.divideAndRemainder(new BigDecimal(60));
    

    Javadoc: https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html#divideAndRemainder-java.math.BigDecimal-

    0 讨论(0)
  • 2020-12-15 03:01
        int result,rest;
        _asm
        {
            xor edx, edx // pone edx a cero; edx = 0
            mov eax, result// eax = 2AF0
            mov ecx, radix // ecx = 4
            div ecx
            mov val, eax
            mov rest, edx
        }
    
    0 讨论(0)
  • 2020-12-15 03:03

    The .NET framework has Math.DivRem:

    int mod, div = Math.DivRem(11, 3, out mod);
    // mod = 2, div = 3
    

    Although, DivRem is just a wrapper around something like this:

    int div = x / y;
    int mod = x % y;
    

    (I have no idea whether or not the jitter can/does optimise that sort of thing into a single instruction.)

    0 讨论(0)
  • 2020-12-15 03:05

    In C#/.NET you've got Math.DivRem: http://msdn.microsoft.com/en-us/library/system.math.divrem.aspx

    But according to this thread this isn't that much an optimization.

    0 讨论(0)
  • 2020-12-15 03:08

    As Stringer Bell mentioned there is DivRem which is not optimized up to .NET 3.5.

    On .NET 4.0 it uses NGen.

    The results I got with Math.DivRem (debug; release = ~11000ms)

    11863
    11820
    11881
    11859
    11854
    

    Results I got with MyDivRem (debug; release = ~11000ms)

    29177
    29214
    29472
    29277
    29196
    

    Project targeted for x86.


    Math.DivRem Usage example

    int mod1;
    int div1 = Math.DivRem(4, 2, out mod1);
    

    Method signatures

    DivRem(Int32, Int32, Int32&) : Int32
    DivRem(Int64, Int64, Int64&) : Int64
    

    .NET 4.0 Code

    [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
    public static int DivRem(int a, int b, out int result)
    {
        result = a % b;
        return (a / b);
    }
    

    .NET 4.0 IL

    .custom instance void System.Runtime.TargetedPatchingOptOutAttribute::.ctor(string) = { string('Performance critical to inline across NGen image boundaries') }
    .maxstack 8
    L_0000: ldarg.2 
    L_0001: ldarg.0 
    L_0002: ldarg.1 
    L_0003: rem 
    L_0004: stind.i4 
    L_0005: ldarg.0 
    L_0006: ldarg.1 
    L_0007: div 
    L_0008: ret 
    

    MSDN Reference

    0 讨论(0)
  • 2020-12-15 03:13

    FWIW, Haskell has both divMod and quotRem that latter of which corresponds directly to the machine instruction (according to Integral operators quot vs. div) while divMod may not.

    0 讨论(0)
提交回复
热议问题