web-dev-qa-db-ja.com

フロートを整数で除算すると0.0が返されるのはなぜですか?

したがって、数値の範囲が「0-1024」であり、それらを「0-255」にしたい場合、数学は、入力を最大値(この場合は1024)で除算するように指示します。 0.0〜1.0の数値。次に、宛先範囲(255)を乗算します。

これが私がやりたいことです!

しかし、何らかの理由でJava(Processingを使用))常に値0を返します。

コードはこれと同じくらい簡単です

float scale;
scale = (n/1024) * 255;

しかし、私は0.0を取得します。 doubleとintを試しました。すべて役に立たない。なぜ!?

40
Arif Driessen

整数除算をしているからです。

Doubleまたはfloatで除算すると、動作します。

double scale = ( n / 1024.0 ) * 255 ;

または、フロートとして使用する場合は、

float scale = ( n / 1024.0f ) * 255 ;
73
tim_yates

n/1024はinteger divisionで、整数(この場合は0)を生成します。

使用する n / 1024.0代わりに。

19
Alexandre C.

nintであると想定しています。定数1024と255は両方ともintsであるため、すべての右側の計算は整数演算で行われています。 n/1024の結果は、255で乗算される前に整数値に切り捨てられます。

これらの変更により、計算が正しく機能します。

scale = n / 1024.0 * 255.0;       // Use double constants.
scale = (double) n / 1024 * 255;  // Convert n to a double.
scale = n * 255 / 1024;           // Multiply before dividing.

最後のものはまだ整数演算を使用していますが、演算の順序を切り替えると、望ましくない切り捨てが0にならないことを意味します。

7
John Kugelman

乗算FIRSTを使用してnをフロートに自動キャストする必要があります。そうでない場合、フロート間で演算を行う代わりに、整数演算を実行してから結果をキャストします。

float scale;
scale = n * 1.0 / 1024 * 255;
2
Agos

あなたの場合、n/1024は整数除算を行っているため0になります。これを克服するには、nfloatにキャストします。これにより、0.01.0の間の結果が得られ、次に255で乗算し、結果を整数にキャストします。また、scaleintとして宣言する必要があります

int scale;
int n = 80; 
scale = (int)(((float)n/1024) * 255);
2
codaddict

他の人はすでに素晴らしい答えを与えています。スケールを整数にしたい場合(nが既に整数の場合は理にかなっています)、次のようにすることができます

int scale = ((255 * n)/1024);

最大n = 1024の場合、n * 255は常にintに収まるため、これらが数値である限り、これで問題が発生することはありません。

より柔軟になります

int scale(int value, int old_max, int new_max){
  Java.math.BigInteger big_value = Java.math.BigInteger.valueOf(value);
  Java.math.BigInteger big_old_max = Java.math.BigInteger.valueOf(old_max);
  Java.math.BigInteger big_new_max = Java.math.BigInteger.valueOf(new_max);
  Java.math.BigInteger mult = big_value.multiply(big_old_max);
  return (int) mult.devide(big_new_max).doubleValue();
}

この方法でintがオーバーフローすることはありませんが、これは少し冗長です

編集:

基本的には同じですが、不格好ではありません(ただし、非常に大きい数値の場合、いくつかの精度エラーが発生する可能性があります)

int scale(int value, int old_max, int new_max){
  double factor = (double) new_max / (double) old_max;
  return factor * value;
}
2
Martijn