C に unsigned float がないのはなぜですか?

C++ が符号なし浮動小数点数をサポートしていないのは、CPU が実行する同等のマシン コード操作がないためです。したがって、それをサポートすることは非常に非効率的です。

C++ がそれをサポートしていた場合、unsigned float を使用していて、パフォーマンスが低下していることに気付かないことがあります。 C++ がサポートしている場合は、すべての浮動小数点演算をチェックして、署名されているかどうかを確認する必要があります。何百万もの浮動小数点演算を行うプログラムでは、これは受け入れられません。

したがって、問題は、ハードウェアの実装者がそれをサポートしない理由です。そして、それに対する答えは、元々定義されていた unsigned float 規格がなかったということだと思います。言語は下位互換性を好むため、追加された言語であってもそれを利用できませんでした。浮動小数点の仕様を確認するには、IEEE 標準 754 浮動小数点を参照する必要があります。

float または double をカプセル化し、負の数を渡そうとすると警告をスローする unsigned float クラスを作成することで、unsigned float 型を持たないようにすることができます。これはあまり効率的ではありませんが、頻繁に使用しなければ、わずかなパフォーマンスの低下は気にならないでしょう。

unsigned float を持つことの有用性は間違いなくわかります。しかし、C/C++ は、安全性よりも、誰にとっても最適な効率性を選択する傾向があります。


C/C++ では、符号付き整数と符号なし整数の間には大きな違いがあります:

value >> shift

符号付きの値はトップ ビットを変更せず (符号拡張)、符号なしの値はトップ ビットをクリアします。

unsigned float がない理由は、負の値がないとあらゆる種類の問題にすぐに遭遇するためです。これを考慮してください:

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

c にはどのような値がありますか? -8.しかし、負の数のないシステムでは、それは何を意味するでしょうか。 FLOAT_MAX - おそらく8?実際には、 FLOAT_MAX - 8 は精度効果のために FLOAT_MAX であるため、機能しないため、さらに厄介です。より複雑な式の一部だったらどうなるでしょうか:

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

2 の補数システムの性質により、これは整数の問題ではありません。

また、標準の数学関数も考慮してください。sin、cos、および tan は入力値の半分でしか機能せず、1 未満の値の対数を見つけることができず、二次方程式を解くことができませんでした:x =(-b +/- root ( b.b - 4.a.c)) / 2.a など。実際、複雑な関数は、どこかで負の値を使用する多項式近似として実装される傾向があるため、おそらく機能しません。

したがって、unsigned float はほとんど役に立ちません。

しかし、これは float 値を範囲チェックするクラスが役に立たないという意味ではありません。RGB 計算など、値を特定の範囲に固定したい場合があります。


(余談ですが、Perl 6 では次のように記述できます

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

Nonnegative::Float を使用できます 他のタイプと同じように。)

符号なし浮動小数点演算はハードウェアでサポートされていないため、C ではサポートされていません。 C はほとんどの場合、「ポータブル アセンブリ」、つまり、特定のプラットフォームに縛られることなく、金属にできるだけ近づけるように設計されています。

[編集]

C はアセンブリのようなものです:見たままのものが得られます。暗黙の「このフロートが負でないことを確認します」は、その設計哲学に反します。本当に必要な場合は、 assert(x >= 0) を追加できます または同様ですが、明示的に行う必要があります。