Floating point OCaml中的IEEE 64位和32位浮点验证

Floating point OCaml中的IEEE 64位和32位浮点验证,floating-point,ocaml,ieee-754,single-precision,Floating Point,Ocaml,Ieee 754,Single Precision,我有一个字符串与下面的regex\-?[0-9]*\.[0-9]+匹配,它应该表示一个IEEE浮点数。它可以是单精度或双精度,而且我提前知道类型。我需要检查它是否可以被解释为给定精度下的有效值。比如: val is_valid_float: string -> bool val is_valid_double: string -> bool 对于双精度数字,我可以使用float\u of_string解析它并捕获异常。我不确定如何处理单精度问题。@JonathanChan的评论很有

我有一个字符串与下面的regex
\-?[0-9]*\.[0-9]+
匹配,它应该表示一个IEEE浮点数。它可以是单精度或双精度,而且我提前知道类型。我需要检查它是否可以被解释为给定精度下的有效值。比如:

val is_valid_float: string -> bool
val is_valid_double: string -> bool

对于双精度数字,我可以使用
float\u of_string
解析它并捕获异常。我不确定如何处理单精度问题。

@JonathanChan的评论很有启发性,可能比我可能说的任何话都更有启发性

然而,我甚至不知道你所说的验证是什么意思

“1.00000000000000001”是有效的浮动吗

 val f : string = "1.0000000000000001"
 # float_of_string f;;
 - : float = 1.
 #
没有例外表明这个数字不能表示为与1.0不同

如果忽略精度问题,就不难像字符串操作一样针对可表示范围进行测试


正如@JonathanChan所指出的,最好的答案可能取决于你需要有多大的把握(以及你想要确切把握的是什么)。

我想知道你是否可以把
Int32.bits\u float
搞得一团糟?进行检查。一些初步测试表明,如果
浮点值超出范围,则
将给出
无穷大。检查OCaml源代码。OCaml源代码仅依赖于C从双精度到浮点的转换(请参见
byterun/ints.C
中的
caml\u int32\u bits\u of_float\u unboxed
)。C规范只是说使用IEEE规范的转换,但该过程似乎很复杂(请参见)。有人可能会假设
int32.float\u of_bits(Int32.bits_of_float float))
确实应该是身份,如果
float
可以表示为一个单精度浮点,但我不是专家,并且假设它可能很危险,这取决于您对此的把握程度!表示范围从-∞ 到+∞, 由于这些值有单精度和双精度两种,因此可能需要检查字符串中的值是否可以精确表示(24/53有效位)而不是通过
+inf
-inf
。这是通过检查转换的结果是否是无限的来完成的。很好。因此,对于词汇有效的字符串,似乎没有异常。但是,似乎您需要另一种单精度浮点方法,因为它在OCaml中没有表示形式。我的方法是s将单精度数字表示为OCaml
float
。大多数单精度操作可以使用OCaml操作进行精确模拟,然后立即舍入到单精度,使用此函数:。但不从十进制解析:需要重新实现此操作,例如,在我尝试复制C编译器和我希望接受它会发现正确的常量。在上面的问题中,我已经将其缩小到特定的regexp,所以我们不需要在这里处理无穷大。