Fast way of finding most and least significant bit set in a 64-bit integer

前端 未结 6 581
名媛妹妹
名媛妹妹 2020-12-14 10:58

There are a lot of questions about this on StackOverflow. A lot. However I cannot find an answer that:

  • Works in C#
  • Works for 64-bit i
6条回答
  •  一个人的身影
    2020-12-14 11:47

    Since we're talking about .NET here, it's usually preferable not to resort to external native calls. But if you can tolerate the overhead of a managed/unmanaged roundtrip for each operation, the following two calls provide pretty direct and unadulterated access to the native CPU instructions.

    The (minimalistic) disassembly of the respective entire functions from ntdll.dll are also shown for each. That library will be present on any Windows machine, and will always be found, if referenced as shown.

    Least-significant bit (LSB):

    [DllImport("ntdll"), SuppressUnmanagedCodeSecurity]
    public static extern int RtlFindLeastSignificantBit(ulong ul);
    
    // X64:
    //      bsf rdx, rcx
    //      mov eax, 0FFFFFFFFh
    //      movzx ecx, dl
    //      cmovne eax,ecx
    //      ret
    

    Most-significant bit (MSB):

    [DllImport("ntdll"), SuppressUnmanagedCodeSecurity]
    public static extern int RtlFindMostSignificantBit(ulong ul);
    
    // X64:
    //      bsr rdx, rcx
    //      mov eax, 0FFFFFFFFh
    //      movzx ecx, dl
    //      cmovne eax,ecx
    //      ret
    

    Usage:
    Here's a usage example which requires that the above declarations be accessible. Couldn't be simpler.

    int ix;
    
    ix = RtlFindLeastSignificantBit(0x00103F0A042C1D80UL);  // ix --> 7
    
    ix = RtlFindMostSignificantBit(0x00103F0A042C1D80UL);   // ix --> 52
    

提交回复
热议问题