2017-03-14 7 views
1

C++の(暗黙的な)型変換に関する小さな問題があります。整数と浮動小数点の変換

float f = 554344.76; 
int x1 = f; 
std::cout << x1 << std::endl; 

プリント554344(切り捨てるまたは小数点以下の切断)をintへフロートしかしfloat f = 5543444.76;とそれを交換するときには、(切り上げ)5543445を印刷します。最初のケースでは切り捨てられ、2番目のケースでは四捨五入されるのはなぜですか?それに加えて、それは完全に奇妙な結果をもたらす(例えば5543444675.765543444480になる)。どうして?

int x1 = f;long int x2 = f;の違いは何ですか?

long int li; 
float x3 = li; 
std::cout << x3 << std::endl; 

に運動への解決策をfloatへ

2. long int型の値が切り捨てされていることを言うと、多数の不正な値の結果。試してみるとlong int li = 5435;は切り捨てられません。または、long int li = 5435.56;を切り捨てた意味ですか?第二に、なぜ大量の数値が不正確になるのでしょうか?長い整数と浮動小数点数は同じビット数だと思います。

3.文字

char c = 130; 
double x4 = c; 
std::cout << x4 << std::endl; 

を倍増させるのはなぜ-126しばらくchar c = 100;でこの結果が正しい値を提供していますか?これは何も(出力なし)を印刷しない

int i = 200; 
char x5 = i; 
std::cout << x5 << std::endl; 

をcharへ

4. int型。どうして? 255までの値を格納できるので、結果は正しくなければならないと思います。

+1

4.チェックするASCIIコード200 .. –

+0

2.浮動小数点をintに初期化すると、小数部は無視されます。 –

+0

1.私は "float f = 5543444.76;で置き換えることを理解していません。"それはすでにそこにあるものです。あなたは何を置き換えますか? – user463035818

答えて

2
  1. フロートは精度の23ビットのみを持っているあなたはchar c = 130をしようとしたとき あなたも、それについての警告を得ている必要があります。 5543444は23ビットに収まらないため、適合する最も近い値に丸められます。

  2. liの初期化されていないので、未定義の動作です。おそらくあなたはあなたが疑問に思っている実際のコードを表示するために質問を編集する必要があります。

  3. charが頻繁に署名されています。 130は符号付きcharとして表すことはできません。これはおそらく未定義の動作です(実際には標準をチェックして実装が定義されているか、特別なルールが存在する可能性があります)が、実際にはPC CPU上でコンパイラは130の8ビットをとり、 8ビットの符号付き文字に変換し、それは8番目のビットを設定し、負の値になります。

  4. 上記3と同じです:200は符号付き8ビット整数には適合しません。これはcharです。代わりに符号ビットの設定が終了し、負の値になります。

3

編集:投稿ごとに1つの質問をしてください。 charが255

に値を格納することができますので、結果が正しいものでなければならない255までここで私は#3、#4

私が思うに答えるこれは間違った仮定です。 (Demo

charが署名され、8ビット(1バイト)が署名されていると、オーバーフローが発生する可能性があります。最大値は127に過ぎません。これは未定義の動作です。

charが署名されているかどうかは、実装に依存しますが、通常はそうです。それは常に1バイト長ですが、 "1バイト"は実装に依存することが許されていますが、ほぼ普遍的に8ビットになります。

実際には、ASCIIテーブルを参照すると、「拡張」ASCIIになる前に最大127にしかなりません。ほとんどのプラットフォームで、それを表示するにはワイド文字タイプが必要です。

#3と#4のコードがオーバーフローしています。

警告:暗黙の定数変換でオーバーフロー

3
  1. フロートは通常、完全に5543444.76を表現するのに十分な精度を持っていません。 floatには、値5543455.0が格納されている可能性があります。 intへのキャストは、丸めが行われる場所ではありません。浮動小数点からintにキャストすると常に10進数が切り捨てられます。 floatの代わりにdoubleを使用するか、値を直接intに割り当てて、その違いを示してください。 floatのビットの

  2. 多くは符号、指数を表すために使用され、それは正確全て値同じサイズのintを表すことができません。繰り返しますが、これは精度の問題です。最下位の桁を破棄して丸め誤差のような予期しない結果を引き起こす必要があります。科学的表記を考えてみましょう。少数の数字を使用して非常に広い範囲の値を表すことができますが、少数の小数点のみが追跡されます。あまり重要でない数字は削除されます。

  3. charは、使用するプラットフォームによって異なる場合があります。あなたのプラットフォームではcharが8ビットで署名されています。つまり、-128から127までの値しか表現できないことを意味します。符号付き整数オーバーフローは未定義であるため、-126にラップするなど、テストケースで何かが行われる可能性があります。

  4. charstd::coutに渡された変数は値を出力しません。その値に関連付けられた文字を印刷します。 this tableを参照してください。値200は、プラットフォーム上で表すことができる最大値であるcharを超えているため、明らかな表現がない文字を表示しようとするなど、何らかの処理が行われる可能性があります。

2
  1. 5543444から最寄りの数。76 IEEE754 32bit浮動小数点は5,543,445.0です。 this IEEE 754 converterを参照してください。したがって、f5543445.0fに等しく、整数に変換すると5543445に切り下げられます。

  2. 特定のシステムでfloatlong intのサイズが同じであっても、1つの値はすべて別の値で表すことはできません。たとえば、0.5flong intとして表すことはできません。同様に、100000002floatとして表すことはできません。最も近いIEEE 754 32ビット浮動小数点は100000000.0f100000008.0fです。
    一般に、浮動小数点表現について読む必要があります。 Wikipediaは良いスタートです。

  3. charは、あなたがにしているシステムに応じてsigned charまたはunsigned charかもしれません。(8ビット)でsigned char場合、130は表現できません。符号付き整数オーバーフロー(UB)が発生し、おそらく-126にラップされます(130 + 126 = 256になります)。一方、100はsigned charの完全に有効な値です。

  4. Extended ASCII Tableでは、200はÈにマップされます。あなたのシステムが拡張ascii(例えばUTF-8で設定されている場合)を扱っていない場合や、この文字を表すフォントがない場合、出力は表示されません。あなたがcharのシステムでsigned charと定義されている場合は、とにかくUBです。

関連する問題