Warum hat C keine vorzeichenlosen Floats?

131

Ich weiß, die Frage scheint seltsam zu sein. Programmierer denken manchmal zu viel. Bitte lesen Sie weiter ...

In CI verwenden signedund unsignedganze Zahlen viel. Ich mag die Tatsache, dass der Compiler mich warnt, wenn ich einer vorzeichenlosen Variablen eine vorzeichenbehaftete Ganzzahl zuweise. Ich erhalte Warnungen, wenn ich vorzeichenbehaftete mit vorzeichenlosen Ganzzahlen vergleiche und vieles mehr.

Ich mag diese Warnungen. Sie helfen mir, meinen Code korrekt zu halten.

Warum haben wir nicht den gleichen Luxus für Schwimmer? Eine Quadratwurzel wird definitiv niemals eine negative Zahl zurückgeben. Es gibt auch andere Stellen, an denen ein negativer Float-Wert keine Bedeutung hat. Perfekter Kandidat für einen nicht signierten Wagen.

Übrigens - ich bin nicht wirklich begeistert von der zusätzlichen Präzision, die ich durch Entfernen des Vorzeichenbits von den Schwimmern erzielen könnte. Ich bin super glücklich mit floats, wie sie gerade sind. Ich möchte einen Float nur manchmal als nicht signiert markieren und die gleichen Warnungen erhalten, die ich mit ganzen Zahlen erhalte.

Mir ist keine Programmiersprache bekannt, die vorzeichenlose Gleitkommazahlen unterstützt.

Irgendeine Idee, warum sie nicht existieren?


BEARBEITEN:

Ich weiß, dass die x87-FPU keine Anweisungen zum Umgang mit nicht signierten Floats hat. Verwenden wir einfach die signierten Float-Anweisungen. Missbrauch (z. B. unter Null) kann als undefiniertes Verhalten angesehen werden, genauso wie der Überlauf von vorzeichenbehafteten Ganzzahlen undefiniert ist.

Nils Pipenbrinck
quelle
4
Interessant, können Sie ein Beispiel für einen Fall veröffentlichen, in dem die Überprüfung der Signaturprüfung hilfreich war?
litb, war dein Kommentar an mich gerichtet? Wenn ja,
Iraimbilanja yeah :) fabs können keine negative Zahl zurückgeben, da sie den absoluten Wert ihres Arguments zurückgibt
Johannes Schaub - litb
Richtig. Ich habe nicht gefragt, wie ein hypothetisches, nicht signiertes Float zur Korrektheit beitragen kann. Was ich gefragt habe, war: In welcher Situation fand Pipenbrinck Int Signedness Typechecking hilfreich (was ihn dazu veranlasste, denselben Mechanismus für Floats zu suchen). Der Grund, den ich frage, ist, dass ich unsignierte völlig nutzlos finde in Bezug auf die Typensicherheit
1
Es gibt eine vorzeichenlose Mikrooptimierung für die Punkt-in-Bereich-Prüfung: ((vorzeichenlos) (p-min)) <(max-min), die nur einen Zweig hat, aber wie immer ist es am besten, ein Profil zu erstellen, um festzustellen, ob es hilft wirklich (ich habe es meistens auf 386 Kernen verwendet, daher weiß ich nicht, wie moderne CPUs damit umgehen).
Skizz

Antworten:

114

Warum C ++ keine vorzeichenlosen Floats unterstützt, liegt daran, dass die CPU keine entsprechenden Maschinencodeoperationen ausführen kann. Es wäre also sehr ineffizient, dies zu unterstützen.

Wenn C ++ dies unterstützt, verwenden Sie manchmal einen nicht signierten Float und bemerken nicht, dass Ihre Leistung gerade beeinträchtigt wurde. Wenn C ++ dies unterstützt, muss jede Gleitkommaoperation überprüft werden, um festzustellen, ob sie signiert ist oder nicht. Und für Programme, die Millionen von Gleitkommaoperationen ausführen, ist dies nicht akzeptabel.

Die Frage wäre also, warum Hardware-Implementierer dies nicht unterstützen. Und ich denke, die Antwort darauf ist, dass ursprünglich kein vorzeichenloser Float-Standard definiert wurde. Da Sprachen gerne abwärtskompatibel sind, können Sprachen sie auch dann nicht nutzen, wenn sie hinzugefügt wurden. Um die Gleitkomma-Spezifikation zu sehen, sollten Sie sich den Gleitkomma-Standard nach IEEE-Standard 754 ansehen .

Sie können jedoch umgehen, dass Sie keinen vorzeichenlosen Gleitkommatyp haben, indem Sie eine vorzeichenlose Gleitkommaklasse erstellen, die einen Gleitkomma- oder Doppeltyp kapselt und Warnungen auslöst, wenn Sie versuchen, eine negative Zahl zu übergeben. Dies ist weniger effizient, aber wenn Sie sie nicht intensiv nutzen, ist Ihnen dieser leichte Leistungsverlust wahrscheinlich egal.

Ich sehe definitiv die Nützlichkeit eines nicht signierten Schwimmers. C / C ++ tendiert jedoch dazu, eine Effizienz zu wählen, die für alle am besten geeignet ist, wenn es um Sicherheit geht.

Brian R. Bondy
quelle
17
C / C ++ erfordert keine spezifischen Maschinencodeoperationen, um die Sprache zu implementieren. Frühe C / C ++ - Compiler könnten Gleitkomma-Code für den 386 generieren - eine CPU ohne FPU! Der Compiler würde Bibliotheksaufrufe generieren, um FPU-Anweisungen zu emulieren. Daher könnte ein Ufloat ohne CPU-Unterstützung durchgeführt werden
Skizz
10
Skizz, obwohl das richtig ist, hat Brian dies bereits angesprochen - da es keinen äquivalenten Maschinencode gibt, wird die Leistung im Vergleich schrecklich sein.
Anthony
2
@ Brian R. Bondy: Ich habe Sie hier verloren: "Weil es keine äquivalenten Maschinencodeoperationen gibt, die die CPU ausführen kann ...". Können Sie das bitte einfacher erklären?
Lazer
2
Der Grund, warum OP Unterstützung für nicht signierte Floats wünschte, waren Warnmeldungen. Es hat also nichts mit der Codegenerierungsphase des Compilers zu tun - nur damit, wie die Typprüfung im Voraus durchgeführt wird. Daher ist die Unterstützung für sie im Maschinencode irrelevant und (wie am Ende der Frage hinzugefügt wurde) normale Gleitkommaanweisungen könnten für die tatsächliche Ausführung verwendet werden.
Joe F
2
Ich bin mir nicht sicher, warum dies die Leistung beeinträchtigen sollte. Genau wie bei int's kann die gesamte zeichenbezogene Typprüfung zur Kompilierungszeit erfolgen. OP schlägt vor, unsigned floatdies regelmäßig floatmit Überprüfungen zur Kompilierungszeit zu implementieren , um sicherzustellen, dass bestimmte nicht aussagekräftige Vorgänge niemals ausgeführt werden. Der resultierende Maschinencode und die Leistung können identisch sein, unabhängig davon, ob Ihre Floats signiert sind oder nicht.
Xanderflood
14

In C / C ++ gibt es einen signifikanten Unterschied zwischen vorzeichenbehafteten und vorzeichenlosen Ganzzahlen:

value >> shift

Vorzeichenbehaftete Werte lassen das oberste Bit unverändert (Vorzeichenverlängerung), vorzeichenlose Werte löschen das oberste Bit.

Der Grund dafür, dass es kein vorzeichenloses Float gibt, ist, dass Sie schnell auf alle möglichen Probleme stoßen, wenn keine negativen Werte vorhanden sind. Bedenken Sie:

float a = 2.0f, b = 10.0f, c;
c = a - b;

Welchen Wert hat c? -8. Aber was würde das in einem System ohne negative Zahlen bedeuten? FLOAT_MAX - 8 vielleicht? Tatsächlich funktioniert das nicht, da FLOAT_MAX - 8 aufgrund von Präzisionseffekten FLOAT_MAX ist, sodass die Dinge noch schwieriger werden. Was wäre, wenn es Teil eines komplexeren Ausdrucks wäre:

float a = 2.0f, b = 10.0f, c = 20.0f, d = 3.14159f, e;
e = (a - b) / d + c;

Dies ist aufgrund der Art des 2-Komplementsystems kein Problem für ganze Zahlen.

Berücksichtigen Sie auch mathematische Standardfunktionen: sin, cos und tan funktionieren nur für die Hälfte ihrer Eingabewerte, Sie konnten das Protokoll der Werte <1 nicht finden, Sie konnten quadratische Gleichungen nicht lösen: x = (-b +/- root ( bb - 4.ac)) / 2.a und so weiter. Tatsächlich würde es wahrscheinlich für keine komplexe Funktion funktionieren, da diese tendenziell als Polynomnäherungen implementiert werden, die irgendwo negative Werte verwenden würden.

Nicht signierte Schwimmer sind also ziemlich nutzlos.

Dies bedeutet jedoch nicht, dass eine Klasse, deren Bereich Gleitkommawerte überprüft, nicht nützlich ist. Möglicherweise möchten Sie Werte auf einen bestimmten Bereich beschränken, z. B. RGB-Berechnungen.

Skizz
quelle
@Skizz: Wenn die Darstellung ein Problem darstellt, meinen Sie, wenn jemand eine Methode zum Speichern von Floats entwickeln kann, die so effizient ist wie 2's complement, gibt es kein Problem mit nicht signierten Floats?
Lazer
3
value >> shift for signed values leave the top bit unchanged (sign extend) Bist du dir da sicher? Ich dachte, das sei implementierungsdefiniertes Verhalten, zumindest für negativ vorzeichenbehaftete Werte.
Dan
@Dan: Ich habe mir gerade den aktuellen Standard angesehen und er besagt tatsächlich, dass er implementiert ist. Ich denke, das ist nur für den Fall, dass es eine CPU gibt, die keine Verschiebung nach rechts mit Vorzeichenverlängerungsanweisung hat.
Skizz
1
Gleitkomma sättigt traditionell (bis - / + Inf) anstatt zu umbrechen. Sie können erwarten, dass der vorzeichenlose Subtraktionsüberlauf auf 0.0Inf oder NaN gesättigt wird . Oder seien Sie einfach undefiniertes Verhalten, wie es das OP in einer Bearbeitung der Frage vorgeschlagen hat. Re: trig-Funktionen: Definieren Sie also keine vorzeichenlosen Eingabeversionen von sinusw. und behandeln Sie deren Rückgabewert als signiert. Die Frage war nicht, float durch nicht signiertes float zu ersetzen, sondern nur unsigned floatals neuen Typ hinzuzufügen .
Peter Cordes
9

(Nebenbei bemerkt, Perl 6 lässt Sie schreiben

subset Nonnegative::Float of Float where { $_ >= 0 };

und dann können Nonnegative::FloatSie wie jeden anderen Typ verwenden.)

Es gibt keine Hardware-Unterstützung für vorzeichenlose Gleitkommaoperationen, daher bietet C diese nicht an. C ist meistens als "tragbare Baugruppe" konzipiert, dh so nah wie möglich am Metall, ohne an eine bestimmte Plattform gebunden zu sein.

[bearbeiten]

C ist wie Montage: Was Sie sehen, ist genau das, was Sie bekommen. Ein implizites "Ich werde überprüfen, ob dieser Schwimmer für Sie nicht negativ ist" widerspricht seiner Designphilosophie. Wenn Sie es wirklich wollen, können Sie hinzufügen assert(x >= 0)oder ähnliches, aber Sie müssen das explizit tun.

kurzlebig
quelle
svn.perl.org/parrot/trunk/languages/perl6/docs/STATUS sagt ja, of ...analysiert aber nicht.
Ephemient
8

Ich glaube, das nicht signierte int wurde erstellt, weil eine größere Wertmarge erforderlich ist, als das signierte int bieten könnte.

Ein Float hat einen viel größeren Spielraum, so dass es nie einen "physischen" Bedarf für einen nicht signierten Float gab. Und wie Sie in Ihrer Frage selbst betonen, ist die zusätzliche 1-Bit-Präzision nichts, wofür man töten könnte.

Bearbeiten: Nachdem ich die Antwort von Brian R. Bondy gelesen habe , muss ich meine Antwort ändern: Er hat definitiv Recht, dass die zugrunde liegenden CPUs keine vorzeichenlosen Float-Operationen hatten. Ich bin jedoch weiterhin der Ansicht, dass dies eine Entwurfsentscheidung war, die auf den oben genannten Gründen beruhte ;-)

Treb
quelle
2
Außerdem ist das Addieren und Subtrahieren von ganzen Zahlen das gleiche vorzeichenbehaftete oder vorzeichenlose Gleitkomma, nicht so sehr. Wer würde die zusätzliche Arbeit leisten, um sowohl signierte als auch nicht signierte Floats zu unterstützen, da eine solche Funktion nur einen relativ geringen Grenznutzen aufweist?
Ephemient
7

Ich denke, Treb ist auf dem richtigen Weg. Für Ganzzahlen ist es wichtiger, dass Sie einen entsprechenden Typ ohne Vorzeichen haben. Dies sind diejenigen, die bei der Bitverschiebung und in Bitmaps verwendet werden . Ein Zeichenstück stört gerade. Wenn Sie beispielsweise einen negativen Wert nach rechts verschieben, wird der resultierende Wert in C ++ definiert. Wenn Sie dies mit einer vorzeichenlosen Ganzzahl tun oder eine solche überlaufen, ist die Semantik perfekt definiert, da kein solches Bit im Weg ist.

Zumindest für Ganzzahlen ist die Notwendigkeit eines separaten Typs ohne Vorzeichen größer als nur das Ausgeben von Warnungen. Alle oben genannten Punkte müssen für Floats nicht berücksichtigt werden. Ich denke, es besteht kein wirklicher Bedarf an Hardware-Unterstützung für sie, und C wird sie zu diesem Zeitpunkt bereits nicht unterstützen.

Johannes Schaub - litb
quelle
5

Eine Quadratwurzel gibt definitiv niemals eine negative Zahl zurück. Es gibt auch andere Stellen, an denen ein negativer Float-Wert keine Bedeutung hat. Perfekter Kandidat für einen nicht signierten Wagen.

C99 unterstützt komplexe Zahlen und eine generische Form von sqrt, ist also sqrt( 1.0 * I)negativ.


Die Kommentatoren haben oben einen leichten Glanz hervorgehoben, da ich mich sqrteher auf das typgenerische Makro als auf die Funktion bezog und es einen skalaren Gleitkommawert durch Abschneiden des Komplexes auf seine reale Komponente zurückgibt:

#include <complex.h>
#include <tgmath.h>

int main () 
{
    complex double a = 1.0 + 1.0 * I;

    double f = sqrt(a);

    return 0;
}

Es enthält auch einen Gehirnfurz, da der Realteil des Quadrats einer komplexen Zahl positiv oder Null ist und sqrt (1,0 * I) sqrt (0,5) + sqrt (0,5) * I nicht -1,0 ist.

Pete Kirkham
quelle
Ja, aber Sie rufen eine Funktion mit einem anderen Namen auf, wenn Sie mit komplexen Zahlen arbeiten. Auch der Rückgabetyp ist unterschiedlich. Guter Punkt!
Nils Pipenbrinck
4
Das Ergebnis von sqrt (i) ist eine komplexe Zahl. Und da die komplexen Zahlen nicht geordnet sind, kann man nicht sagen, dass eine komplexe Zahl negativ ist (dh <0)
Quinmars
1
Quinmars, sicher, dass es nicht csqrt ist? oder redest du über Mathe statt C? Ich stimme trotzdem zu, dass es ein guter Punkt ist :)
Johannes Schaub - Litb
In der Tat habe ich über Mathematik gesprochen. Ich habe mich nie mit den komplexen Zahlen in c befasst.
Quinmars
1
"Quadratwurzel wird definitiv niemals eine negative Zahl zurückgeben." -> sqrt(-0.0)produziert oft -0.0. Natürlich ist -0,0 kein negativer Wert .
chux
4

Ich denke, es hängt davon ab, dass nur die IEEE-Gleitkomma-Spezifikationen signiert sind und dass die meisten Programmiersprachen sie verwenden.

Wikipedia-Artikel zu IEEE-754-Gleitkommazahlen

Bearbeiten: Wie von anderen angemerkt, unterstützt die meiste Hardware keine nicht negativen Floats. Daher ist die normale Art von Floats effizienter, da Hardware unterstützt wird.

Tobias Wärre
quelle
C wurde lange vor dem Erscheinen des IEEE-754-Standards eingeführt
phuclv
@phuclv Weder waren gängige Gleitkomma-Hardware. Es wurde "einige" Jahre später in Standard C übernommen. Es gibt wahrscheinlich einige Dokumentationen darüber im Internet. (Auch der Wikipedia-Artikel erwähnt C99).
Tobias Wärre
Ich verstehe nicht, was du meinst. Ihre Antwort enthält keine "Hardware", und IEEE-754 wurde nach C geboren, sodass Gleitkommatypen in C nicht vom IEEE-754-Standard abhängen können, es sei denn, diese Typen wurden viel später in C eingeführt
phuclv
@phuclv C ist / war auch als tragbare Baugruppe bekannt, daher kann es der Hardware ziemlich nahe kommen. Sprachen gewinnt im Laufe der Jahre an Funktionen, auch wenn (vor meiner Zeit) float in C implementiert wurde, war es wahrscheinlich eine softwarebasierte Operation und ziemlich teuer. Zum Zeitpunkt der Beantwortung dieser Frage hatte ich offensichtlich ein besseres Verständnis für das, was ich zu erklären versuchte, als jetzt. Und wenn Sie sich die akzeptierte Antwort ansehen, werden Sie vielleicht verstehen, warum ich den IEE754-Standard erwähnt habe. Was ich nicht verstehe, ist, dass Sie eine 10 Jahre alte Antwort ausgewählt haben, die nicht akzeptiert wird?
Tobias Wärre
3

Ich denke, der Hauptgrund ist, dass nicht signierte Floats im Vergleich zu nicht signierten Ints nur eine sehr begrenzte Verwendung haben würden. Ich kaufe nicht das Argument, dass es daran liegt, dass die Hardware es nicht unterstützt. Ältere Prozessoren hatten überhaupt keine Gleitkommafunktionen, alles wurde in Software emuliert. Wenn nicht signierte Floats nützlich wären, wären sie zuerst in Software implementiert worden, und die Hardware wäre diesem Beispiel gefolgt.

Ferruccio
quelle
4
Der PDP-7, die erste Plattform von C, verfügte optional über eine Hardware-Gleitkommaeinheit. Der PDP-11, die nächste Plattform von C, verfügte über 32-Bit-Floats in der Hardware. 80x86 kam eine Generation später, mit einer Technologie, die eine Generation dahinter lag.
Ephemient
3

Ganzzahlige Typen ohne Vorzeichen in C werden so definiert, dass sie den Regeln eines abstrakten algebraischen Rings entsprechen. Wenn Sie beispielsweise für einen Wert X und Y XY zu Y hinzufügen, erhalten Sie X. Ganzzahlige Typen ohne Vorzeichen befolgen diese Regeln garantiert in allen Fällen, in denen keine Konvertierung in oder von einem anderen numerischen Typ [oder vorzeichenlose Typen unterschiedlicher Größe] erforderlich ist. und diese Garantie ist eines der wichtigsten Merkmale solcher Typen. In einigen Fällen lohnt es sich, die Darstellung negativer Zahlen im Austausch für die zusätzlichen Garantien aufzugeben, die nur nicht signierte Typen bieten können. Gleitkommatypen, ob signiert oder nicht, können nicht alle Regeln eines algebraischen Rings einhalten [z. B. können sie nicht garantieren, dass X + YY gleich X ist], und IEEE tut dies tatsächlich nicht. ' Sie dürfen nicht einmal die Regeln einer Äquivalenzklasse einhalten [indem sie verlangen, dass bestimmte Werte ungleich mit sich selbst verglichen werden]. Ich glaube nicht, dass ein "vorzeichenloser" Gleitkommatyp Axiome einhalten könnte, die ein gewöhnlicher Gleitkommatyp nicht könnte, daher bin ich mir nicht sicher, welche Vorteile er bieten würde.

Superkatze
quelle
1

IHMO liegt daran, dass die Unterstützung von vorzeichenbehafteten und vorzeichenlosen Gleitkommatypen in Hardware oder Software zu problematisch wäre

Für Integer - Typen können wir verwenden die gleiche Logik - Einheit für beide mit und ohne Vorzeichen Integer - Operationen in den meisten Fällen mit der schönen Eigenschaft von 2-Komplement, weil das Ergebnis in diesen Fällen identisch ist für add, sub, nicht-Erweiterung mul und die meisten Bit - Operationen. Für Operationen, die zwischen signierter und nicht signierter Version unterscheiden, können wir immer noch den größten Teil der Logik teilen . Beispielsweise

  • Arithmetische und logische Verschiebung erfordern nur eine geringfügige Änderung des Füllers für die oberen Bits
  • Die Erweiterung der Multiplikation kann dieselbe Hardware für den Hauptteil und dann eine separate Logik verwenden, um das Ergebnis anzupassen und die Vorzeichen zu ändern . Nicht, dass es in echten Multiplikatoren verwendet wird, aber es ist möglich
  • Der vorzeichenbehaftete Vergleich kann einfach durch Umschalten des oberen Bits oder HinzufügenINT_MIN in einen vorzeichenlosen Vergleich umgewandelt werden und umgekehrt . Auch theoretisch möglich, wird es wahrscheinlich nicht auf Hardware verwendet, aber es ist nützlich auf Systemen, die nur einen Vergleichstyp unterstützen (wie 8080 oder 8051).

Systeme, die das Komplement von 1 verwenden, müssen ebenfalls nur geringfügig an der Logik geändert werden, da es sich lediglich um das Übertragsbit handelt, das auf das niedrigstwertige Bit umwickelt ist. Ich bin mir bei Vorzeichengrößen-Systemen nicht sicher, aber es scheint, als würden sie das 1-Komplement intern verwenden, sodass das Gleiche gilt

Leider haben wir diesen Luxus für Gleitkommatypen nicht. Durch einfaches Freigeben des Vorzeichenbits erhalten wir die vorzeichenlose Version. Aber wofür sollen wir dieses Bit dann verwenden?

  • Erhöhen Sie den Bereich, indem Sie ihn dem Exponenten hinzufügen
  • Erhöhen Sie die Präzision, indem Sie sie der Mantisse hinzufügen. Dies ist oft nützlicher, da wir im Allgemeinen mehr Präzision als Reichweite benötigen

Beide Optionen benötigen jedoch einen größeren Addierer , um den breiteren Wertebereich zu berücksichtigen . Dies erhöht die Komplexität der Logik, während das oberste Bit des Addierers die meiste Zeit unbenutzt dort sitzt. Für Multiplikationen, Divisionen oder andere komplexe Operationen werden noch mehr Schaltungen benötigt

Auf Systemen, die Software-Gleitkomma verwenden, benötigen Sie 2 Versionen für jede Funktion, die während der Zeit nicht erwartet wurden. Der Speicher war so teuer, oder Sie müssten einen "kniffligen" Weg finden, um Teile der signierten und nicht signierten Funktionen gemeinsam zu nutzen

Allerdings Gleitkomma-Hardware gab es schon lange vor dem C erfunden wurde , so dass ich die Wahl in C war wegen der fehlenden Hardware - Unterstützung , weil der Grund glaube ich oben erwähnt

Es gibt jedoch mehrere spezialisierte Gleitkommaformate ohne Vorzeichen, hauptsächlich für Bildverarbeitungszwecke, wie den 10- und 11-Bit-Gleitkommatyp der Khronos-Gruppe

phuclv
quelle
0

Ich vermute, das liegt daran, dass die zugrunde liegenden Prozessoren, auf die C-Compiler abzielen, nicht gut mit vorzeichenlosen Gleitkommazahlen umgehen können.

Brian Ensink
quelle
Hatten die zugrunde liegenden Prozessoren eine gute Möglichkeit, mit vorzeichenbehafteten Gleitkommazahlen umzugehen? C wurde immer beliebter, als Gleitkomma-Hilfsprozessoren eigenwillig und kaum universell waren.
David Thornley
1
Ich kenne nicht alle historischen Zeitpläne, aber es gab eine neue Hardware-Unterstützung für signierte Floats, obwohl dies, wie Sie betonen, selten ist. Sprachdesigner könnten Unterstützung dafür einbinden, während Compiler-Backends je nach Zielarchitektur unterschiedliche Unterstützungsstufen hatten.
Brian Ensink
0

Gute Frage.

Wenn es sich, wie Sie sagen, nur um Warnungen zur Kompilierungszeit und keine Änderung ihres Verhaltens handelt, ist die zugrunde liegende Hardware nicht betroffen und als solche nur eine C ++ / Compiler-Änderung.

Ich habe das gleiche schon früher gewonnen, aber die Sache ist: Es würde nicht viel helfen. Bestenfalls kann der Compiler statische Zuordnungen finden.

unsigned float uf { 0 };
uf = -1f;

Oder minimalistisch länger

unsigned float uf { 0 };
float f { 2 };
uf -= f;

Aber das war es schon. Bei vorzeichenlosen Ganzzahltypen erhalten Sie auch einen definierten Wraparound, der sich wie eine modulare Arithmetik verhält.

unsigned char uc { 0 };
uc -= 1;

danach hat 'uc' den Wert 255.

Was würde ein Compiler mit demselben Szenario bei einem vorzeichenlosen Float-Typ tun? Wenn die Werte zur Kompilierungszeit nicht bekannt sind, muss Code generiert werden, der zuerst die Berechnungen ausführt und dann eine Vorzeichenprüfung durchführt. Was aber, wenn das Ergebnis einer solchen Berechnung "-5,5" lautet - welcher Wert sollte in einem Float gespeichert werden, der als vorzeichenlos deklariert wurde? Man könnte modulare Arithmetik wie für integrale Typen versuchen, aber das bringt seine eigenen Probleme mit sich: Der größte Wert ist unbestreitbar unendlich ... das funktioniert nicht, man kann nicht "unendlich - 1" haben. Wenn Sie sich für den größten eindeutigen Wert entscheiden, den es halten kann, funktioniert dies auch nicht wirklich, da Sie dort auf die Präzision stoßen. "NaN" wäre ein Kandidat.

Schließlich wäre dies bei Festkommazahlen kein Problem, da Modulo gut definiert ist.

ABaumstumpf
quelle