سؤال

كل ما أحاول تنفيذ مكتبة حسابية ذات نقطة عائمة ولديك مشكلة في فهم خوارزمية طرح العوامات. لقد نفذت إضافة ناجحة وناجح أن الطرح كان مجرد حالة خاصة به ولكن يبدو أنني أخطأ في مكان ما. أقوم بإضافة الكود هنا للرجوع إلى الإشارة فقط، ولديه العديد من الوظائف التفسيرية الذاتية لكنني لا أتوقع أن يفهمه شخص ما 100٪. ما أود المساعدة هو الخوارزمية. نتبع نفس الطريقة كما هو الحال مع إضافة أرقام تعويم باستثناء، عندما نضيف mantissas، نقوم بتحويل المرء السلبي (الذي نطرحه) في تكمل اثنين ثم يضيفها؟

هذا ما أقوم به ولكن النتيجة غير صحيحة. وإن كان قريبا جدا ... ولكن ليس هو نفسه. أي شخص لديه أي أفكار؟ شكرا مقدما!

أنا متأكد تماما من أن الطريقة التي أقوم بها بأشياء تعمل منذ أن قمت بتنفيذ خوارزمية متطابقة تقريبا لإضافة العوامات ويعمل مثل سحر.

_float subFloat(_float f1,_float f2)
{
unsigned char diff;
_float result;

//first see whose exponent is greater
if(f1.float_parts.exponent > f2.float_parts.exponent)
{
    diff = f1.float_parts.exponent - f2.float_parts.exponent;

    //now shift f2's mantissa by the difference of their exponent to the right
    //adding the hidden bit
    f2.float_parts.mantissa = ((f2.float_parts.mantissa)>>1) | (0x01<<22);
    f2.float_parts.mantissa >>= (int)(diff);//was (diff-1)

    //also increase its exponent by the difference shifted
    f2.float_parts.exponent = f2.float_parts.exponent + diff;
}
else if(f1.float_parts.exponent < f2.float_parts.exponent)
{
    diff = f2.float_parts.exponent - f1.float_parts.exponent;
    result = f1;
    f1 = f2;        //swap them
    f2 = result;

    //now shift f2's mantissa by the difference of their exponent to the right
    //adding the hidden bit
    f2.float_parts.mantissa = ((f2.float_parts.mantissa)>>1) | (0x01<<22);
    f2.float_parts.mantissa >>= (int)(diff);

    //also increase its exponent by the difference shifted
    f2.float_parts.exponent = f2.float_parts.exponent + diff;
}
else//if the exponents were equal
  f2.float_parts.mantissa = ((f2.float_parts.mantissa)>>1) | (0x01<<22); //bring out the hidden bit




//getting two's complement of f2 mantissa
f2.float_parts.mantissa ^= 0x7FFFFF;
f2.float_parts.mantissa += 0x01;



result.float_parts.exponent = f1.float_parts.exponent;
result.float_parts.mantissa = (f1.float_parts.mantissa +f2.float_parts.mantissa)>>1;
                                                //gotta shift right by overflow bits

//normalization
if(manBitSet(result,1))
    result.float_parts.mantissa <<= 1;  //hide the hidden bit
else
    result.float_parts.exponent +=1;

return result;

}
هل كانت مفيدة؟

المحلول

إذا كان رمز الإضافة الخاص بك هو الصحيح، فلن تكون الطرح الخاص بك، فإن المشكلة مفترضة في تكمل الوثنين بالإضافة إلى ذلك.

هل من الضروري القيام باستكمال الوثنين والإضافة، بدلا من الطرح؟

إذا لم تكن هذه هي المشكلة، أواجه مشكلة في خوارزميةك. لقد مر بعض الوقت منذ أن فعلت أي شيء مثل هذا. هل يمكنك تقديم بعض التفاصيل؟ وبشكل أكثر تحديدا، ما هو الشيء المخفي؟

يبدو من الممكن لي أن التعامل مع بت مخفي مناسب للإضافة ولكن ليس الطرح. هل يمكن أن يكون لديك أنه يجب عليك تعيينه في F1 Mantissa بدلا من F2؟ أو ينفي F1 Mantissa بدلا من F2؟

دون معرفة ما تحصل عليه مقابل ما تتوقعه، ومزيد من التفاصيل من الخوارزمية التي تستخدمها، هذا هو أفضل ما يمكنني القيام به.

تحرير: حسنا، نظرت إلى المراجع في تعليقك. شيء واحد تفشل في القيام به في التعليمات البرمجية الموردة هو التطبيع. عند الإضافة، إما تجاوزات البتات المخفية (SHIFT MANTISSA إلى اليسار أو الزيادة المستردة) أو لا يفعلون ذلك. عند طرح الأجزاء التعسفية من Mantissa يمكن أن يكون صفر. في عشري، النظر في إضافة 0.5E1 و 0.50001E1؛ تحصل على 1.00001E1 وإذا كنت تطبيعا، فستحصل على 0.10001E2. عند طرح 0.5E1 من 0.50001E1، تحصل على 0.00001E1. ثم تحتاج إلى تحويل Mantissa إلى اليسار وانخفاض الأساس بقدر ما يتطلبه الأمر، للحصول على 0.1E-4.

نصائح أخرى

a-b == a+(-b), ، وحيون ناقص هو تافهة، لذلك لن أزعج حتى من ناقص ثنائي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top