Skip to content

index encode double wrong #3034

Closed
Closed
@cangfengzhs

Description

@cangfengzhs
  static std::string encodeDouble(double v) {
    if (v < 0) {
      /**
       *   TODO : now, the -(std::numeric_limits<double>::min())
       *   have a problem of precision overflow. current return value is -nan.
       */
      auto i = *reinterpret_cast<const int64_t*>(&v);
      i = -(std::numeric_limits<int64_t>::max() + i);
      v = *reinterpret_cast<const double*>(&i);
    }
    auto val = folly::Endian::big(v);
    auto* c = reinterpret_cast<char*>(&val);
    c[0] ^= 0x80;
    std::string raw;
    raw.reserve(sizeof(double));
    raw.append(c, sizeof(double));
    return raw;
  }

0.0 and -4.9406564584124654e-324,-0.0 and 4.9406564584124654e-324, encoding string are the same.

Detail:
(For simplicity, we use two bytes instead of eight bytes)

4.9406564584124654e-324 0.0 -0.0 -4.9406564584124654e-324
origin 0001 0000 1000 1001
+max 1111 0000
negative 0001 0000
^\x80 1001 1000 1001 1000

Suggestion:
In TiKV and yugabyteDB: negative values have all bits negated while positive values have the high bit turned on.
In MyRocks: Outside of the way above, exponent of positive values gets incremented.But I don’t know the meaning of doing this.

https://github.com/yugabyte/yugabyte-db/blob/d28d82e8c48bb068b538a3ea0e5165525e46838d/src/yb/util/kv_util.h#L67:6
https://github.com/pingcap/tidb/blob/master/util/codec/float.go
https://github.com/facebook/mysql-5.6/wiki/MyRocks-record-format

Metadata

Metadata

Assignees

Labels

incompatiblePR: incompatible with the recently released versiontype/bugType: something is unexpected

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions