简体   繁体   English

Datastreams浮点Java

[英]Datastreams floating point Java

If the next statement is true: 如果下一个陈述是真的:

DataStreams uses one very bad programming technique: it uses floating point numbers to represent monetary values. DataStreams使用一种非常糟糕的编程技术:它使用浮点数来表示货币值。 In general, floating point is bad for precise values. 通常,浮点对于精确值是不利的。 It's particularly bad for decimal fractions, because common values (such as 0.1) do not have a binary representation. 对于小数分数尤其不好,因为常见值(例如0.1)没有二进制表示。

It's then true that datastreams are to be used only for non floating point values? 那么数据流只能用于非浮点值吗? It's not that useful if it is in this way. 如果是这样的话,那就不那么有用了。

The quote is confusing for a number of reasons 引用令人困惑,原因有很多

DataStreams uses one very bad programming technique: it uses floating point numbers to represent monetary values. DataStreams使用一种非常糟糕的编程技术:它使用浮点数来表示货币值。

DataStream don't have anything to say about how monetary values are sent. DataStream没有任何关于如何发送货币值的说法。 There is no send Price/Money/Currency methods. 没有发送价格/货币/货币方法。 How you send monetary values is entirely up to you, 你如何发送货币价值完全取决于你,

In general, floating point is bad for precise values. 通常,浮点对于精确值是不利的。

float is very bad for precise values as it only has 6 digits of precision. float对于精确值非常糟糕,因为它只有6位数的精度。 double on the other hand has at least 15 digits of precision and this is usually more than enough for money. 另一方面, double至少有15位数的精度,这通常绰绰有余。 ie you can accurately represent values up to $70,000,000,000,000.00 即您可以准确地表示高达$ 70,000,000,000,000.00的价值

In general, I would avoid float as it isn't worth the memory you save (unless you have millions or billions of them) 一般来说,我会避免浮动,因为它不值得你保存的记忆(除非你有数百万或数十亿)

It's particularly bad for decimal fractions, because common values (such as 0.1) do not have a binary representation. 对于小数分数尤其不好,因为常见值(例如0.1)没有二进制表示。

This does not have a precise binary representation, something the double to text conversion implicitly compensate for. 这没有精确的二进制表示,双重到文本转换隐含地补偿。 eg 例如

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.

While representation errors can be a head ache, they are not random errors which some people seems to believe. 虽然表示错误可能是头痛,但它们并不是某些人似乎相信的随机错误。 They can be determined and controlled with sensible rounding. 它们可以通过合理的舍入来确定和控制。

Never the less if you want to use BigDecimal for your values, you can and you can write this to a DataStream. 如果你想使用BigDecimal作为你的值,你可以,你可以将它写入DataStream。

BTW C and C++ don't have a decimal type and yet many trading systems (in the past most trading systems) used these languages. BTW C和C ++没有十进制类型,但许多交易系统(过去大多数交易系统)都使用这些语言。 They did this by using int , long and double types in general, as do many Java based trading systems. 他们通常使用intlongdouble类型来做到这一点,就像许多基于Java的交易系统一样。 Most investment banks in London use double AFAIK. 伦敦的大多数投资银行都使用double AFAIK。 (I have worked at more than a few ;) (我已经工作了不少;)

It's then true that datastreams are to be used only for non floating point values? 那么数据流只能用于非浮点值吗?

A common misused of DataInputStream is for reading text. DataInputStream的常见误用是读取文本。 There are about 30 questions and answer posted to SO a month which use DataInputStream to read text from a file and it is something I am actively trying to stop. 大约有30个问题和答案发布到SO一个月,它使用DataInputStream从文件中读取文本,这是我正在积极尝试停止的。

However DataInputStream is useful for reading all primitive types, Strings and reading a full byte[] eg 但是,DataInputStream可用于读取所有基本类型,字符串和读取完整字节[],例如

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

Note: the DataStream assume Big Endian or Network order. 注意:DataStream假定Big Endian或Network order。 Unfortunately most desktop and mobile systems use Little Endian meaning you need to use ByteBuffer if you want to exchange data with a C program. 不幸的是,大多数桌面和移动系统都使用Little Endian,这意味着如果要与C程序交换数据,则需要使用ByteBuffer。


If you want a simple comparison of how inefficient BigDecimal compared with double 如果你想简单比较BigDecimal与double相比效率如何

  • BigDecimal is approximately 100x slower to perform basic calculations and it does not support complex ones that double does. BigDecimal执行基本计算的速度大约慢100倍,并且它不支持复杂的双重计算。
  • double produces no garbage, BigDecimal produces a lot. double不产生垃圾,BigDecimal产生很多。
  • Writing one double to a stream 8 bytes, write one BigDecimal to an ObjectOutputStream 290 bytes. 将一个double写入一个8字节的流,将一个BigDecimal写入一个280字节的ObjectOutputStream。

What BigDecimal does for you is give you precise and controlled rounding built in. With double you have to know how to use functions like Math.round, Math.floor, Math.ceil to do the same thing. BigDecimal为您做的是为您提供精确且受控的内置舍入。使用double,您必须知道如何使用Math.round,Math.floor,Math.ceil等函数来执行相同的操作。

DataStream implementations don't reduce the precision of the data types that were written. DataStream实现不会降低写入的数据类型的精度。

If you write an float value using writeFloat(..) you will read exactly the same value using readFloat() . 如果您在使用编写浮点值writeFloat(..)你会读到准确使用相同的值readFloat() There is only lost of precision when you convert values, eg from double to float. 转换值时,例如从double到float,只会丢失精度。 But that this is not related to DataStreams. 但这与DataStreams无关。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM