Datastreams浮点Java

时间:2013-04-27 08:52:30

标签: java floating-point data-stream

如果下一个statement为真:

  

DataStreams使用一种非常糟糕的编程技术:它使用浮动   点数代表货币价值。一般来说,浮点   对于精确的值是不好的。十进制特别糟糕   分数,因为公共值(例如0.1)没有二进制   表示。

那么数据流只能用于非浮点值吗? 如果是这样的话,那就不那么有用了。

2 个答案:

答案 0 :(得分:3)

由于多种原因,引用令人困惑

  

DataStreams使用一种非常糟糕的编程技术:它使用浮点数来表示货币值。

DataStream对如何发送货币值没有任何说法。没有发送价格/货币/货币方法。你如何发送货币价值完全取决于你,

  

通常,浮点对精确值不利。

float对于精确值非常糟糕,因为它只有6位精度。另一方面,double具有至少15位精度,这通常足以赚钱。即,您可以准确地表示高达$ 70,000,000,000,000.00的价值

一般情况下,我会避免浮动,因为它不值得你保存的记忆(除非你有数百万或数十亿)

  

对于小数部分尤其如此,因为常见值(例如0.1)没有二进制表示。

这没有精确的二进制表示,双向文本转换隐含地补偿。 e.g。

double d = 0.1; // no a precise representation
System.out.println(d); // print 0.1 as the conversion is aware this what should be displayed.

虽然表示错误可能是一种头痛,但它们并不是某些人似乎相信的随机错误。它们可以通过合理的舍入来确定和控制。

如果您想将BigDecimal用于您的值,那么您可以将其写入DataStream。

BTW C和C ++没有小数类型,但许多交易系统(过去大多数交易系统)都使用这些语言。他们通常使用intlongdouble类型来完成此操作,许多基于Java的交易系统也是如此。伦敦的大多数投资银行使用double AFAIK。 (我已经在不止一些工作;)

  

那么数据流只用于非浮点值吗?

DataInputStream的常见误用是读取文本。每月大约有30个问题和答案发布到SO,它使用DataInputStream从文件中读取文本,这是我正在积极尝试停止的。

然而,DataInputStream可用于读取所有基本类型,字符串和读取完整字节[],例如

byte[] bytes = new byte[64];
dataInputSTream.readFully(bytes); // don't return unless 64 bytes have been read.

注意:DataStream假定Big Endian或Network order。不幸的是,大多数桌面和移动系统都使用Little Endian,这意味着如果你想与C程序交换数据,你需要使用ByteBuffer。


如果你想简单比较BigDecimal与double的低效率

  • BigDecimal执行基本计算的速度大约慢100倍,并且它不支持复用的复杂算法。
  • double不产生垃圾,BigDecimal产生很多。
  • 将一个double写入一个8字节的流,将一个BigDecimal写入一个290字节的ObjectOutputStream。

BigDecimal为您做的是为您提供内置的精确控制舍入。使用double,您必须知道如何使用Math.round,Math.floor,Math.ceil等函数来执行相同的操作。

答案 1 :(得分:1)

DataStream实现不会降低写入的数据类型的精度。

如果使用writeFloat(..)写一个浮点值,您将使用readFloat()读取完全相同的值。转换值时,只会丢失精度,例如:从double到float。但这与DataStreams无关。