【问题标题】:double vs long serialization in javajava中的双序列化与长序列化
【发布时间】:2012-09-23 19:45:12
【问题描述】:

我可以在 HBase 中将数字存储为 Long 和 Double。在 Java 中它们都占用 8 个字节。

使用 Double 的优点是它为存储整数提供了更广泛的范围。

但是,我认为 Long 的范围也足够我使用。

有人知道 Long vs Dobule 的序列化和反序列化性能吗?我对它们之间的比较感兴趣。

谢谢。

【问题讨论】:

  • long and double or Long and Double 你说的是什么序列化?

标签: java performance serialization deserialization hbase


【解决方案1】:

如果您要存储整数,请使用Long。您关于“使用 Double 的优势在于它为存储整数提供了更广泛的范围” 的说法是不正确的。两者都是 64 位长,但double 必须使用一些位作为指数,留下更少的位来表示幅度。您可以将更大的数字存储在 double 中,但会丢失精度。

换句话说,对于大于某个上限的数字,您不能再存储相邻的“整数”...给定一个高于此阈值的整数值,“下一个”可能的 double 将大于 1上一个号码。

例如

public class Test1  
{

    public static void main(String[] args) throws Exception 
    {
        long   long1 = Long.MAX_VALUE - 100L;
        double dbl1  = long1;
        long   long2 = long1+1;
        double dbl2  = dbl1+1;
        double dbl3  = dbl2+Math.ulp(dbl2);

        System.out.printf("%d %d\n%f %f %f", long1, long2, dbl1, dbl2, dbl3);
    }

}

这个输出:

9223372036854775707 9223372036854775708
9223372036854776000.000000 9223372036854776000.000000 9223372036854778000.000000

注意

  1. Lo​​ng.MAX_VALUE-100 的双重表示等于原始值
  2. 对 Long.MAX_VALUE-100 的双重表示加 1 无效
  3. 在这个量级上,一个双精度值与下一个可能的双精度值之间的差值为 2000。

另一种说法是long 的精度不到 19 位,而 double 的精度只有 16 位。 Double 可以存储大于 16 位的数字,但代价是对低位数字进行截断/四舍五入。

如果您需要超过 19 位的精度,则必须求助于BigInteger,预计性能会下降。

【讨论】:

  • +1 - 性能无关;这两种类型的用途完全不同。
  • 是的,我要存储整数(整数)。如果我将整数存储在 Double 中,你能告诉我如何丢失精度吗?双最大值为:长的17976931348623157000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0最大值为:9223372036854775807 跨度>
  • 我无法理解“对于大于某个上限的数字,您不能再存储相邻的“整数”......给定一个高于此阈值的整数值,“下一个”可能的双精度数将是比前一个数字大 1 以上。”你能详细说明一下吗? Long 的问题是它只能有 19 位数字,将来我可能会有一个超过 19 位数字的数字。
  • 关于更广范围的说法是正确的。 double 的精度较低,但范围较大。
  • 这就是为什么您绝不能使用浮点数进行财务计算。
【解决方案2】:

这看起来像是一场错误的战斗:

来自Java Tutorial

long 数据类型是一个 64 位有符号二进制补码整数。它有 最小值为 -9,223,372,036,854,775,808,最大值为 9,223,372,036,854,775,807(含)。

这非常接近 19 位有效数字

来自Wikipedia

这给出了 15 - 17 位有效十进制数字的精度。

因此,尽管 Double 具有明显的“优势”,但它对你的服务会比 Long 更差。我只是在这里猜测,但直觉上我会说浮点类型的序列化/反序列化是比整数数据类型的相同操作更昂贵的操作,但即使存在差异,它们在现代系统上也会非常小。

因此,在处理整数时,请坚持使用 Long。

【讨论】:

  • Long 的问题是我的整数中可能有超过 19 个有效数字。
【解决方案3】:

在不知道具体情况的情况下,我可以想象longdouble 具有相同的序列化:获取 64 位并将它们放在网络上。同样,我想反序列化只是从线路上取下 64 位并声明它们现在代表longdouble 的问题。任何 64 位都将代表一个有效的 longdouble(尽管不是所有的都代表一个有限的双精度),所以没有任何验证或额外的工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-19
    • 1970-01-01
    • 2018-11-10
    • 1970-01-01
    • 2021-06-10
    相关资源
    最近更新 更多