Frage

all Ich versuche, eine Gleitkomma-Arithmetik-Bibliothek zu implementieren, und ich habe Schwierigkeiten zu verstehen, um den Algorithmus zu subtrahieren schwimmt. Ich habe zusätzlich erfolgreich umgesetzt und ich dachte, dass Subtraktion war nur ein Spezialfall davon, aber es scheint, ich mache einen Fehler irgendwo.  Ich bin der Code hier nur als Referenz hinzugefügt, es hat viele erklärenden Funktionen selbst aber ich erwarte nicht, dass jemand es zu 100% zu verstehen. Was würde Ich mag Hilfe bei dem Algorithmus. Wir folgen dem gleichen Verfahren wie bei Zugabe von Fließkommazahlen, außer, wenn wir die Mantissen hinzufügen, wandeln wir die negative (die wir subtrahieren) in Zweier-Komplement und sie fügen Sie dann?

Das ist, was ich tue, aber das Ergebnis ist nicht korrekt. Allerdings ist es sehr nah ... aber nicht gleich. Jeder hat irgendwelche Ideen? Vielen Dank im Voraus!

Ich bin ziemlich sicher, dass die Art, wie ich Dinge tun, funktioniert, da ich einen fast identischen Algorithmus für das Hinzufügen von Schwimmern implementiert und es funktioniert wie ein Charme.

_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;

}
War es hilfreich?

Lösung

Wenn Ihr Zusatz-Code korrekt ist, und Ihre Subtraktion ist nicht, das Problem ist vermutlich in dem Zweierkomplement und Addition.

Ist es notwendig, das Zweierkomplement und zusätzlich, anstatt Subtraktion zu tun?

Wenn das nicht das Problem ist, ich habe Probleme mit dem Algorithmus. Es ist schon eine Weile her, seit ich etwas Derartiges getan hat. Könnten Sie einige Details zur Verfügung stellen? Genauer gesagt, was das versteckte Bit ist?

Es scheint mir möglich, dass die Handhabung des versteckten Bit für die Zugabe richtig ist, aber nicht Subtraktion. Könnte es sein, dass Sie es in der f1 Mantisse anstatt die f2 gesetzt haben? Oder negieren die f1 Mantisse anstelle des f2?

Ohne zu wissen, was Sie bekommen im Vergleich zu, was Sie erwartet, und mehr Details des Algorithmus Sie verwenden, das ist das Beste, was ich tun kann.

Edit: OK, ich auf den Referenzen in Ihrem Kommentar aussehen. Eine Sache, die Sie andernfalls in dem mitgelieferten Code zu tun, ist eine Normalisierung. Beim Hinzufügen, entweder die versteckte Bits Überlauf (verschieben Mantisse nach links, erhöhe Exponent), oder sie es nicht tun. Wenn subtrahieren, beliebige Teile der Mantisse kann Null sein. In dezimal, betrachten 0.5E1 und 0.50001E1 Zugabe; Sie würden 1.00001E1 bekommen und wenn Sie Sie 0.10001E2 bekommen würde zu normalisieren waren. Wenn die 0.5E1 von 0.50001E1 subtrahieren, erhalten Sie 0.00001E1. Dann müssen Sie mit so viel die Mantisse nach links und verringern die Exponenten verschieben, wie es dauert, zu bekommen 0.1E-4.

Andere Tipps

a-b == a+(-b) und einstellige minus ist trivial, also würde ich mit binärer minus nicht einmal die Mühe.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top