5

私は低遅延システムに取り組んでおり、2 進数をバイト配列に変換するソリューションが必要ですが、10 進数の精度は必要です。ソリューション内でのオブジェクトの作成を減らす必要があることを考慮する必要があります。また、私は二重の価値を得ています。

私の現在の実装はやや似ています

int offset = 0;
double d = 1211.11;
long integerPart = (long) d;
byte[] b = new byte[16];

offset += addToByteArray(integerPart, b, offset); 
//implementation to add each digit to byte array, returns new offset

int lengthDecimal = 16 - offset;
if(lengthDecimal > 0)
b[offset++] = '.';
long tmp = 1;

for(int i=0; i<lengthDecimal; i++){
 tmp = tmp * 10;
 int digit = (int)(((long) (d * tmp)) % 10);
 b[offset++] = (byte) ('0' + digit);
}

次に、バイト配列が操作されて、後のゼロと「.」が削除されます。もし必要なら。

問題は、バイト配列をチェックすると、正確な数字が見つからないことです。double を使用しているため、作業中に小数点の精度が失われます。

BigDecimal を使用する場所を検索して見つけました。BigDecimal の使用は問題ないようですが、コードのこの部分が頻繁にヒットするため、パフォーマンスと作成されるオブジェクトの数が心配です。

私はまた、このような文字列を操作しようとしました

String doubleNumber = Double.toString(d);
long fractionalPart = 0;

offset += addToByteArray(integerPart, b, offset); 
if(doubleNumber.substring(doubleNumber.indexOf(".")).length() > 0) {
  fractionalPart = Long.valueOf(doubleNumber.substring(doubleNumber.indexOf(".") + 1));
  b[offset++] = '.';
  offset += addToByteArray(fractionalPart, b, offset);
}

目的に最適なアプローチを提案してください。

4

3 に答える 3

10
byte[] bytes = new byte[8];
java.nio.ByteBuffer.wrap(bytes).putDouble(yourDouble);
于 2012-12-28T00:03:19.243 に答える
4

本当に低レイテンシが必要な場合、重要なことは、ヒープメモリの割り当てを回避することです(これにより、GCが後で指定されていない時点で一時停止します)。

だから私はそれを仮定しています:

  • 事前にバイト配列を割り当てています
  • 中間割り当てを行わずにバイト配列にdoubleを入れたい

秘訣は使用することdoubleToLongBitsです:

long v = Double.doubleToLongBits(myDouble);

long次に、をバイト配列の正しい位置に書き込みます(おそらく8つの連続したバイトを使用します)。これを力ずくの方法で行う方がよいでしょう。

data[pos+7] = (byte)(v);
data[pos+6] = (byte)(v>>>8);
data[pos+5] = (byte)(v>>>16);
data[pos+4] = (byte)(v>>>24);
data[pos+3] = (byte)(v>>>32);
data[pos+2] = (byte)(v>>>40);
data[pos+1] = (byte)(v>>>48);
data[pos]   = (byte)(v>>>56);

すべてのポイントでプリミティブを使用しているため、このプロセス全体でメモリの割り当てはありません。

于 2012-12-28T00:22:13.337 に答える
-2

double を ASCII (文字) 文字列にフォーマットする場合は、おそらく String.format がフォーマットを制御できる最も簡単な方法です。

String result = String.formatter("%5.3f", theDoubleValue);
于 2012-12-28T00:28:15.537 に答える