Bigarray类型之间的转换

时间:2020-02-25 13:12:34

标签: ocaml

考虑这3个大数组:

open Bigarray
let arr_float32 = Array1.of_array Float32 c_layout [|42.0|]
let arr_uint8 = Array1.of_arrayInt8_unsigned c_layout [|42|]
let arr_float32_as_uint8 = Array1.of_array Int8_unsigned c_layout [|0; 0; 40; 66|]
  1. 是否有一种强制转换arr_float32使其(在类型和值上)等于arr_uint8的方法?
  2. 是否有一种方法可以重新解释arr_float32,使其与arr_float32_as_uint8相等(在类型和值上)?

[|0; 0; 40; 66|]42.0的小尾数表示形式

2 个答案:

答案 0 :(得分:0)

强制转换(IMHO)的正常含义是产生新值,而不是更改某物的值。换句话说,您的第一个问题只是问是否有一种方法可以计算这个新的bigarray。有一种方法可以通过创建一个新的bigarray并在原始数组的每个元素上使用int_of_float来进行计算。

如果不超出语言的范围来刺穿抽象,就无法重新解释bigarray中的值(或者实际上是OCaml中的任何值)。

答案 1 :(得分:0)

您正在尝试更改值的类型。这实际上是类型系统所不允许的。类型系统专门存在,所以您不能(偶然)这样做。

有时候,没有理由为什么必须这样做。通常是为了表现。为此的功能是Obj.magic : 'a -> 'b。如类型所示,Obj.magic可以使用任何类型并输出任何其他类型。它像魔术一样改变类型。 :)

仅应在精确控制的情况下这样做。您必须知道自己在做什么,并且在使用Obj.magic时可以这样做。最好尽可能明确地注释Obj.magic周围的类型,以免得到任何随机结果。在您的情况下,请指定输入和输出Bigarray的类型。

内部,大数组只是内存的一小部分,对于切片操作来说有些参考计数。对于get / set方法,有一些编译器魔术可以根据数组的类型进行优化。因此,对数组的访问必须与您访问的类型正确对齐。例如,不要试图使子数组位于int8数组的偏移量1处,并以float形式对其进行访问。这将在许多CPU上失败。但是直接使用它们应该可以。

让我重复一遍:当心您正在做一些事情来绕过类型系统。 Obj.magic根本不检查您是否在做任何理智的事情。知道您在这里做什么是您的工作。我之前使用Obj.magic投放了Bigarrays,但我相信这样做是安全的。如果我错了,它应该会迅速崩溃,因为Obj.magic通常无法幸免于误操作。