Can anyone explain this strange behavior with signed floats in C#?

前端 未结 11 2017
别跟我提以往
别跟我提以往 2020-12-07 07:17

Here is the example with comments:

class Program
{
    // first version of structure
    public struct D1
    {
        public double d;
        public int f         


        
11条回答
  •  一整个雨季
    2020-12-07 07:39

    The bug is in the following two lines of System.ValueType: (I stepped into the reference source)

    if (CanCompareBits(this)) 
        return FastEqualsCheck(thisObj, obj);
    

    (Both methods are [MethodImpl(MethodImplOptions.InternalCall)])

    When all of the fields are 8 bytes wide, CanCompareBits mistakenly returns true, resulting in a bitwise comparison of two different, but semantically identical, values.

    When at least one field is not 8 bytes wide, CanCompareBits returns false, and the code proceeds to use reflection to loop over the fields and call Equals for each value, which correctly treats -0.0 as equal to 0.0.

    Here is the source for CanCompareBits from SSCLI:

    FCIMPL1(FC_BOOL_RET, ValueTypeHelper::CanCompareBits, Object* obj)
    {
        WRAPPER_CONTRACT;
        STATIC_CONTRACT_SO_TOLERANT;
    
        _ASSERTE(obj != NULL);
        MethodTable* mt = obj->GetMethodTable();
        FC_RETURN_BOOL(!mt->ContainsPointers() && !mt->IsNotTightlyPacked());
    }
    FCIMPLEND
    

提交回复
热议问题