1 //------------------------------------------------------------------------------
2 // <copyright file="SingleStorage.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">Microsoft</owner>
6 // <owner current="true" primary="false">Microsoft</owner>
7 // <owner current="false" primary="false">Microsoft</owner>
8 //------------------------------------------------------------------------------
10 namespace System
.Data
.Common
{
13 using System
.Data
.SqlTypes
;
14 using System
.Collections
;
16 internal sealed class SingleStorage
: DataStorage
{
18 private const Single defaultValue
= 0.0f
;
20 private Single
[] values
;
22 public SingleStorage(DataColumn column
)
23 : base(column
, typeof(Single
), defaultValue
, StorageType
.Single
) {
26 override public Object
Aggregate(int[] records
, AggregateType kind
) {
30 case AggregateType
.Sum
:
31 Single sum
= defaultValue
;
32 foreach (int record
in records
) {
35 checked { sum += values[record];}
43 case AggregateType
.Mean
:
44 Double meanSum
= (Double
)defaultValue
;
46 foreach (int record
in records
) {
49 checked { meanSum += (Double)values[record];}
55 checked {mean = (Single)(meanSum / meanCount);}
60 case AggregateType
.Var
:
61 case AggregateType
.StDev
:
63 double var = (double)defaultValue
;
64 double prec
= (double)defaultValue
;
65 double dsum
= (double)defaultValue
;
66 double sqrsum
= (double)defaultValue
;
68 foreach (int record
in records
) {
71 dsum
+= (double)values
[record
];
72 sqrsum
+= (double)values
[record
]*(double)values
[record
];
77 var = ((double)count
* sqrsum
- (dsum
* dsum
));
78 prec
= var / (dsum
* dsum
);
80 // we are dealing with the risk of a cancellation error
81 // double is guaranteed only for 15 digits so a difference
82 // with a result less than 1e-15 should be considered as zero
84 if ((prec
< 1e-15) || (var <0))
87 var = var / (count
* (count
-1));
89 if (kind
== AggregateType
.StDev
) {
90 return Math
.Sqrt(var);
97 case AggregateType
.Min
:
98 Single min
= Single
.MaxValue
;
99 for (int i
= 0; i
< records
.Length
; i
++) {
100 int record
= records
[i
];
103 min
=Math
.Min(values
[record
], min
);
111 case AggregateType
.Max
:
112 Single max
= Single
.MinValue
;
113 for (int i
= 0; i
< records
.Length
; i
++) {
114 int record
= records
[i
];
117 max
=Math
.Max(values
[record
], max
);
125 case AggregateType
.First
:
126 if (records
.Length
> 0) {
127 return values
[records
[0]];
131 case AggregateType
.Count
:
132 return base.Aggregate(records
, kind
);
136 catch (OverflowException
) {
137 throw ExprException
.Overflow(typeof(Single
));
139 throw ExceptionBuilder
.AggregateException(kind
, DataType
);
142 override public int Compare(int recordNo1
, int recordNo2
) {
143 Single valueNo1
= values
[recordNo1
];
144 Single valueNo2
= values
[recordNo2
];
146 if (valueNo1
== defaultValue
|| valueNo2
== defaultValue
) {
147 int bitCheck
= CompareBits(recordNo1
, recordNo2
);
151 return valueNo1
.CompareTo(valueNo2
); // not simple, checks Nan
154 public override int CompareValueTo(int recordNo
, object value) {
155 System
.Diagnostics
.Debug
.Assert(0 <= recordNo
, "Invalid record");
156 System
.Diagnostics
.Debug
.Assert(null != value, "null value");
158 if (NullValue
== value) {
159 if (IsNull(recordNo
)) {
165 Single valueNo1
= values
[recordNo
];
166 if ((defaultValue
== valueNo1
) && IsNull(recordNo
)) {
169 return valueNo1
.CompareTo((Single
)value);
172 public override object ConvertValue(object value) {
173 if (NullValue
!= value) {
175 value = ((IConvertible
)value).ToSingle(FormatProvider
);
184 override public void Copy(int recordNo1
, int recordNo2
) {
185 CopyBits(recordNo1
, recordNo2
);
186 values
[recordNo2
] = values
[recordNo1
];
189 override public Object
Get(int record
) {
190 Single
value = values
[record
];
191 if (value != defaultValue
) {
194 return GetBits(record
);
197 override public void Set(int record
, Object
value) {
198 System
.Diagnostics
.Debug
.Assert(null != value, "null value");
199 if (NullValue
== value) {
200 values
[record
] = defaultValue
;
201 SetNullBit(record
, true);
204 values
[record
] = ((IConvertible
)value).ToSingle(FormatProvider
);
205 SetNullBit(record
, false);
209 override public void SetCapacity(int capacity
) {
210 Single
[] newValues
= new Single
[capacity
];
211 if (null != values
) {
212 Array
.Copy(values
, 0, newValues
, 0, Math
.Min(capacity
, values
.Length
));
215 base.SetCapacity(capacity
);
218 override public object ConvertXmlToObject(string s
) {
219 return XmlConvert
.ToSingle(s
);
222 override public string ConvertObjectToXml(object value) {
223 return XmlConvert
.ToString((Single
)value);
226 override protected object GetEmptyStorage(int recordCount
) {
227 return new Single
[recordCount
];
230 override protected void CopyValue(int record
, object store
, BitArray nullbits
, int storeIndex
) {
231 Single
[] typedStore
= (Single
[]) store
;
232 typedStore
[storeIndex
] = values
[record
];
233 nullbits
.Set(storeIndex
, IsNull(record
));
236 override protected void SetStorage(object store
, BitArray nullbits
) {
237 values
= (Single
[]) store
;
238 SetNullStorage(nullbits
);