3

私が取り組んでいるプロジェクトでは、JavaScript番号(double)をBLOB主キーとしてデータベーステーブルに格納する必要があります(データベースのネイティブfloatデータ型は使用できません)。したがって、基本的には、次のような方法で数値をバイト配列にシリアル化する必要があります。

1-バイト配列の長さは8です(これは、doubleをシリアル化するために通常必要な長さです)

2-データベースがインデックスbツリーの行を透過的にソートするように、バイト配列は自然な順序を維持する必要があります。

数値を受け取り、バイトを表す数値の配列を返す単純な関数が、私が探しているものです。関数はjavascriptで記述したほうがいいですが、java、C、C#、C ++、またはpythonでの回答も受け入れられます。

4

3 に答える 3

5

並べ替えの要件を満たすには、次のことを行う必要があります。

  1. ビッグエンディアン表現を使用
  2. 符号ビットが 0 の場合は、1 に反転します。実際のビットを確認します。元の数値を 0 と比較すると、負のゼロなどの特殊なケースでは異なる結果が得られます。
  3. 符号ビットが 1 の場合、すべてのビットを反転する

Python 3 コード:

import struct

def invert(x):
    return bytes(c ^ 255 for c in x)

def tobin(x):
    binx = struct.pack('>d', x)
    if binx > b'\x80': #negative
        return invert(binx)
    else:
        return struct.pack('>d', -x)

data = [float('-inf'), -100.0, -2.0, -.9, -.1, -0.0, 
    0.0, .1, .9, 2.0, 100.0, float('inf'), float('nan')]

print(sorted(data, key=tobin))
#[-inf, -100.0, -2.0, -0.9, -0.1, -0.0, 0.0, 0.1, 0.9, 2.0, 100.0, inf, nan]

Python 2 では、次のように変更invertします。

def invert(x):
    return "".join(chr(ord(c) ^ 255) for c in x)

For reference, here is the equivalent node.js which already implements a Big Endian serialization function through the 'Buffer' class:

function serialize(n) {
  var buffer = new Buffer(8);
  var l = buffer.length;
  buffer.writeDoubleBE(n, 0);
  if (buffer[0] < 0x80) {
    buffer[0] ^= 0x80;
  } else {
    for (var i = 0; i < l; i++) 
      buffer[i] ^= 0xff;
  }
  return buffer
}

function deserialize(buffer) {
  var l = buffer.length;
  // 0x80 is the most significant byte of the representation of
  // the first positive number(Number.MIN_VALUE)
  if (buffer[0] >= 0x80) { 
    buffer[0] ^= 0x80;
  } else {
    for (var i = 0; i < l; i++) 
      buffer[i] ^= 0xff;
  }
  return buffer.readDoubleBE(0);
}
于 2012-10-17T11:56:02.900 に答える
0

DataViewは、8 バイト コンテナーに double を書き込むための API を提供します。

メソッドgetFloat64()setFloat64()

言及されたリンクは明らかにsetFloat64()を実装していませんが、少なくともそのような関数の作成に関係するものを提供します。

https://github.com/vjeux/jDataView

ブラウザーの場合、間違いなく最善かつ最速のアプローチは、型付き配列から Float64Array を使用することです (そして、おそらくバイト オーダーを修正します)。

于 2012-10-17T10:57:31.787 に答える
0

明らかな答えは、ネイティブ データベース タイプを使用できないという制限を取り除くことです。そこには何の意味もありません。それはまだ 8 バイトであり、それ以上の調査、作業、実験、テストなどを必要とせずに順序付けを行います。

于 2012-10-17T11:39:18.613 に答える