表中不寻常的浮点数

时间:2013-02-26 09:45:36

标签: java floating-point

我正在构建一个从异构文档中读取表的系统,并希望了解管理(列)浮点数的最佳方法。如果列可以表示为实数,我将使用List<Double>(我正在使用Java,但是使用其他语言的经验会很有用。)我还希望将表序列化为CSV文件。因此,表格可能如下所示:

"material", "mass (g)", "volume (cm3)",
"iron", 7.8, 1.0,
"aluminium", 27.3, 9.9,

和column2(从1开始)将由List<Double>

表示
{new Double(7.8), new Double(27.3)} 

我可能还希望计算密度(质量/体积)并得到一个新列(“密度(g.cml-3)”)作为列表

{new Double(7.8), new Double(2.76)} 

然而,输入值有时会丢失,不常见或由模糊概念表示。一些转换可能会抛出异常(我会抓住并替换上面的一个)。例子包括:

1.0E+10000
>10
10 / 0.0 (i.e. divide by zero)
Math.sqrt(-1.)
Math.tan(Math.PI/2.0)

对于列表元素的异常值,我有以下options in Java

  1. null reference
  2. Double.NaN
  3. Double.MAX_VALUE
  4. Double.POSITIVE_INFINITY
  5. 是否应该使用上述Java异常值的协议?关于他们的行为我有read this question。 (我想依靠链接他们的操作)。如果有协议可以将值序列化并重新读回? (例如,Java会将"0x7ff0000000000000L"解析为等于Double.POSITIVE_INFINITY

    的数字

    我已经准备好在规范中失去一些精确度(OCR中经常出现错误,缺少数字等等。所以这是一个“足够好”的练习)。

1 个答案:

答案 0 :(得分:1)

你有三个问题应该在某种程度上分开:

  1. 您应该对表格条目使用什么表示形式,可能是数字,某些单位的编号或其他内容?

  2. 浮点无穷大和NaN如何为您服务?

  3. 如何对浮点对象进行序列化(写入文件并从文件中读取)?

  4. 关于这些:

    1. 您尚未在此处指定足够的信息,以获取有关如何表示表条目的良好建议。根据您的描述,根本没有理由使用浮点数。这是因为您没有指定要对读取和写入条目以外的条目执行哪些操作。如果您不需要算术,则没有理由将值转换为浮点或任何其他数字算术系统。您可以简单地将条目保留为原始文本。这使序列化变得微不足道。

    2. 根据设计,浮点无穷大就像数学无穷大。无穷大加上无穷大以外的数字仍然是无穷大等等。你应该使用浮点无穷大来表示数学无穷大。您应该避免使用浮点无穷大来表示溢出,除非您不关心丢失溢出的值。浮点NaN旨在表示“非数字”。它通常用于表示“发生错误,所以我们这里没有数字给你。你应该在这个地方做点什么。“然后由应用程序提供其他东西,可能是通过从其他来源或并行数据结构中获取补充信息。错误包括诸如取负数的平方根或未能初始化某些数据之类的内容。 (例如,一些底层软件将浮点数据初始化为NaN,因此,如果你不自己初始化它,NaNs仍然存在。)你通常应该将NaN视为“空位”,你不能使用它而不是代表某些东西的标记

    3. 在编写和读取浮点值时,您应该注意转换完全的值,或者确保您在转换中引入的错误是可以容忍的。如果你必须转换为文本(人类可读的数字)而不是写入“二进制”(具有任意值的字节),那么最好使用与浮动的原始基数兼容的数字基础的符号来编写 - 点系统(例如,二进制浮点表示的十六进制浮点数,例如.8125的0x3.4p-2)。如果这不可行,那么您需要生成足够的数字(转换为十进制时)以足够准确地表示浮点值,以便在读取时恢复原始值,并且您需要确保转换软件转换而不会引入其他错误。您还必须处理特殊值,如无穷大和NaN。

    4. (注意Math.tan(Math.PI/2)不是无穷大并且不会导致异常,因为Math.PI/2不完全是π/ 2,所以它的切线是有限的,而不是无穷大。)