如何从1D数组转换为DBL?

我给一个.net的代码吧!!
一如果你查询的记录中字段只有一个的话如Demo一:
如果你有多个字段的话处理方式见Demo二:

这样就可以解决你的问题了!!

}

labview同其它任何高级语言一样,都支持多种基本数据类型和复合数据类型,基本数据类型包括U8、U16、U32、I8、I16、I32,SGL,DBL,EXT等等,复合数据类型包括数组、簇、字符串、路径等。

同其它高级语言一样,也拥有基本的程序结构,比如,顺序结构、条件结构,循环结构等。也拥有一些自己独特的程序结构,如队列、通告、信号、集合等等。

无论是数据类型还是程序结构,都是和内存的使用紧密地结合在一起的,所以深入地了解数据类型和类型之间的转换以及结构在内存中的存储形式是非常重要的。

LABVIEW 中涉及到数据类型转换时,会引起内存复制操作。大的数据类型结构比如数组,字符串和簇在内存中实际占的空间比我们预想的要大,因为LABVIEW同时在内存中也增加了很多必要的信息,正如我们在类型描述符中谈到的。使用局部变量和全局变量也要引起内存的复制操作,但是,恰当的编程方式可以避免这个问题。

(一)类型转换是如何使用内存的

类型转换会产生两个问题:增加了类型转换时间 需要开辟新的BUFFER,增大了内存空间的使用。

有些类型转换是必要的,但是更多的情况下是我们编程时不注意造成的,对于人为发生的类型转换要极力避免。

LV是图形化编程方式,连线的颜色和线型代表了不同的数据类型,同时在转换处还会有一个强制转换点,一般是黑色或者红色,我们很容易看到在那里发生了隐含的类型转换。


上面三个都是要完成+1操作,由于+节点虽然是多态的,可以适应各种数据类型,但是默认是DOUBLE型的,由于我先生成了常量1,黄色,导致U32在+节点处发生的类型转换,最后输出的是DOUBLE类型。而第二个我是先连接的U32,后自动生成的常量1,LABVIEW自动产生的U32常量而不是 DOUBLE,第三个直接调用+1节点,所以不会发生类型转换。所以编程风格是非常重要


上面的图中,因为SUBVI需要的是DOUBLE类型的数组,而输入数组是I16的,所以产生了一个强制转换点,因此,会产生同I16SIZE相同的额外的DOUBLE数组。
对于SIZE非常大的数组,不恰当的类型转换耗费的内存是惊人的,看下面的图


上图第一个框图,循环产生K的数组,因为没有类型转换,有效地内存重用,数据流上的执行数据是80K,前面板数组指示器的操作数据是80K,总计160K

看看上图中第二个框图,他用了惊人的400K,不过是乘以一个扩展精度的标量,形成一个扩展精度的数组,然后右重新强制转换成DOUBLE数组。看一下是如何产生的。

可以看出中间乘法端子出现的EXT是毫无意义的,不经意间,额外的240K内存被耗费掉了。

所以在数据流中如果数据类型不变,我们将节省240K的内存,一个重要的原则就是:

尽量始终在数据流中保持同一种数据类型


上图中,EXAMPEL1和EXAMPLE2是基本相当的,一个是隐含的强制转换点,一个是用显式的SGL--》DOUBLE转换节点,
它们用的内存是完全相同的,但性能稍微有些差异,隐含转换速度稍微快了一点,并且节省的框图的空间,比较方便。

而EXAMPE 3和EXAMPLE 4则是完全不同的,EXAPLE 3发生了二次隐含强制转换,而EXAPLE 4只有一次显式转换。节省了内存和运行时间。

转换的位置也是很重要的,看看下面的图

方法一中,两个数组分别产生8K的数据,其中上面的A的8K经过乘法后得到重用,在转换C处,产生了4K的执行数据(SGL 4BYTE),加上指示器中的操作数据4K,总计24K

方法二中,两个数组分别产生8K的数据,显式转换后,C、D处各产生4K的执行数据,乘法后C处的4K得到重用,加上指示器中操作数据4K,总计:8k+8k+4k+4k+4k=28k

方法三中,循环中对DOUBLE数据显式转换成SGL,因此两个数组各产生4K的数据,其中A处的4K经过乘法节点后得到重用,加上指示器的4K,总计12K。

对于标量,比如DOUBLE,64位,8个字节,即使发生了强制类型转换,可以不必要考虑的它的内存损失。对于字符串和数组,由于它的SIZE是很容易被改变的又没有SIZE限制,要特别重视。

LABVIEW中的数组和字符串操作是最影响内存的使用和程序的运行速度。它影响速度的原因在于不断调用内存管理器来改变数组或者字符串的SIZE,LABVIEW本身也会在必要的时候改变数组和字符串的存储位置,比如在内存紧张的时候,可能被转移到虚拟内存。

上面的节点是需要特别注意的,因为它们都直接改变的数组和字符串的大小(元素个数),需要不断地调用内存管理器,如果是在一个循环中,会极大地降低程序的性能。

数组所占内存的总量,等于元素个数(size)乘以每个元素所占字节数。
比如包含10000个数据的DOUBLE类型,DOUBLE 64位,8个字节,占内存总量=10K*8=80K,但这是数组最后所占的字节数。当你改变数组大小时,由于LV不能重用输入BUFFER,必须进行额外的内存复制,所以在改变的过程中,会极大消耗内存。所以为了有效地利用内存,尽量不要在循环中改变数组或者字符串的大小。这样就可以重用输入BUFFER 到输出BUFFER。

建立一个数组有很多种方式,各种方式有很大区别。


for循环是固定次数循环,因此在循环开始之前,就会为索引输出的数组申请内存空间,一次完成,在循环内部,不需要改变数组的大小,因此效率是最高的。

第二种方法是效率最差的,每次循环时都要增加数组的大小,循环调用内存管理器,是需要极力避免的方法。

第三种方法用的初始化数组节点,整个数组的的内存空间也是一次申请的,在循环中替换数组的各个元素,而替换操作是可以重用内存的,这也是一个常用的比较好的方法,但是FOR循环是LV的基本结构,所以无疑效率是最高的。

}

Offset是中的函数,在Excel中,OFFSET函数的功能为以指定的引用为参照系,通过给定得到新的引用。返回的引用可以为一个或。并可以指定返回的行数或列数。Reference 作为参照系的引用区域。Reference 必须为对或相连的引用;否则,函数 OFFSET 返回#VALUE!。

Rows相对于偏移量参照系的左上角单元格,上(下)偏移的行数。行数可为正数(代表在起始引用的下方)或负数(代表在起始引用的上方)。

Cols 相对于偏移量参照系的左上角单元格,左(右)偏移的列数列数可为正数(代表在起始引用的右边)或负数(代表在起始引用的左边)。

高度,即所要返回的引用区域的行数。Height 可以为负,-x表示当前行向上的x行。

宽度,即所要返回的引用区域的列数。Width 可以为负,-x表示当前行向左的x行。

简单来说,Offset功能可以理解为:“寻找指定位置”并返回该位置的值。(可以看作在玩飞行棋)

其中的参数reference —— 该次“寻找”的“起点”

目的:让E8单元格显示北京市在19年5月的CPI,即B4中的值

过程:以A1为起点,先向下走3格到达A4,再向右走1格到达目的地B4。返回B4的值,E8被赋值为101.8.

拓展:在下拉,右拉之后,我们发现——在这种情况下,使用“E8=offset(A1,3,1)”与使用"E8=B4"的效果是一样的(实现了矩阵的复制),那么我们使用这个函数的必要性在哪呢?  

所以,我如果再提出一个问题:让这个矩阵实现如下图所示的转置(此时"E8=B4"就不管用了)

对于这个问题,我们分2步来进行分析求解

  • 在进行下拉操作时,如何将起点右边的数据放在终点的下方?如图中如何将北京,天津,河北竖着放?

  1. 在说明这个操作之前,我们先了解——当我们进行所谓的“下拉”,“右拉”操作时,对于新增单元格来说,它们的函数是怎样变化的。

从上图中可以发现——“下拉”时,offset函数中的参数中,对于单个的数值(如3,1)是不变的,而对于坐标(字母与数字的组合,如A1)—— 下拉时,坐标的行标(A1中“1”→“2”)增加,列标不变;右拉时,坐标的列数(A1中"A"→"B")增加,行标不变。

    2. 在了解了“下拉”的变化后,我们再来看所要达到的目的——A1右方数据放于A1下方位置。对此,我们可以让下拉时使得“行的变化”转化成“列的变化”,即使得“E8的‘下’一个新增单元格”   对应   “A1的‘右’一个单元格”。

要完成上述操作:首先我们需要“固定起点”。因此我们使用“$”符号,其表示绝对引用,当进行上下拉或左右拉时,$后的字母或数字保持不变。因此offset的第一个参数(起点坐标)固定为A1————Offset($A$1,...);

那再来看看我们的目的:“行转竖”

相当于——当下拉使得函数中的行标增加(12→...)时,函数中的offset中的单次右移量cols随之增加。

因此,我们使用ROW()函数来反应列标的变化,并将它放在offset的cols位置来让cols随之增加。

其次,我们需要:每次E8向下拉一下,E9数值来源(E9中offset的终点)相对于E8数值来源(A1)来说,向下移动0格,向左移动一格。所以需要在E8的函数中便表明,一旦下拉(某一坐标的行标变化)就要同时使得offset中右移的格数加一(cols+1)。因此对于E8的Offset的第二,三个参数(下移,右移格数)————Offset($A$1,0,row(A1)-1); row()是一个函数,其功能为返回括号内左边的行数,例如row(A4) = 4; row(A2) = 2; row(B5) = 5;使用该函数的作用就是 当我们下拉时A1中的1会递增,我们借用这个递增的数,实现cols+1的目的。】

最后,对于Offset后两个参数,由于我们移动的是单元格,所以不需要给值,其默认为1,1。效果如下:

  • 在进行右拉操作时,如何将起点下方的数据放在终点的右方?如图中如何将2019年7月,2019年6月,...横着放?

有了上方“横转竖”的基础,我们再来看“竖转行”的函数。首先我们尝试就Offset($A$1,0,row(A1)-1)函数向右拉,看看会出现什么情况。

可以发现,右拉之后的单元格中所有的内容的都与A1相同。这是由于当我们右拉时,只有row(A1)中的A(列数)递增,然而人家row函数只返回行数“1”,傻眼了吧?!就是说到头来,里面什么都没变,当然都与A1一样.

那再来看看我们的目的:“竖转行”

相当于——当右拉使得函数中的列标增加(AB→...)时,函数中的offset中的单次下移量rows随之增加。

因此,我们使用COLUMN()函数来反应列标的变化,并将它放在offset的rows位置来让rows随之增加。

}

我要回帖

更多关于 线性值到db的转换 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信