したがって、数値の範囲が「0-1024」であり、それらを「0-255」にしたい場合、数学は、入力を最大値(この場合は1024)で除算するように指示します。 0.0〜1.0の数値。次に、宛先範囲(255)を乗算します。
これが私がやりたいことです!
しかし、何らかの理由でJava(Processingを使用))常に値0を返します。
コードはこれと同じくらい簡単です
float scale;
scale = (n/1024) * 255;
しかし、私は0.0を取得します。 doubleとintを試しました。すべて役に立たない。なぜ!?
整数除算をしているからです。
Doubleまたはfloatで除算すると、動作します。
double scale = ( n / 1024.0 ) * 255 ;
または、フロートとして使用する場合は、
float scale = ( n / 1024.0f ) * 255 ;
n/1024はinteger divisionで、整数(この場合は0)を生成します。
使用する n / 1024.0
代わりに。
n
はint
であると想定しています。定数1024と255は両方ともint
sであるため、すべての右側の計算は整数演算で行われています。 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にならないことを意味します。
乗算FIRSTを使用してnをフロートに自動キャストする必要があります。そうでない場合、フロート間で演算を行う代わりに、整数演算を実行してから結果をキャストします。
float scale;
scale = n * 1.0 / 1024 * 255;
あなたの場合、n/1024
は整数除算を行っているため0になります。これを克服するには、n
をfloat
にキャストします。これにより、0.0
と1.0
の間の結果が得られ、次に255
で乗算し、結果を整数にキャストします。また、scale
をint
として宣言する必要があります
int scale;
int n = 80;
scale = (int)(((float)n/1024) * 255);
他の人はすでに素晴らしい答えを与えています。スケールを整数にしたい場合(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;
}