!B (Sandbox) (CE-21795) Importing models with multisubmaterials via fbx switches...
[CRYENGINE.git] / Code / Tools / LuaRemoteDebugger / LuaRemoteDebugger / MiscUtil / EndianBitConverter.cs
blobccfa89e5ae3e4dcfaec1ae4d71acb8da3d608c1a
1 // Copyright 2001-2019 Crytek GmbH / Crytek Group. All rights reserved.
3 using System;
4 using System.Runtime.InteropServices;
6 namespace MiscUtil.Conversion
8 /// <summary>
9 /// Equivalent of System.BitConverter, but with either endianness.
10 /// </summary>
11 public abstract class EndianBitConverter
13 #region Endianness of this converter
14 /// <summary>
15 /// Indicates the byte order ("endianess") in which data is converted using this class.
16 /// </summary>
17 /// <remarks>
18 /// Different computer architectures store data using different byte orders. "Big-endian"
19 /// means the most significant byte is on the left end of a word. "Little-endian" means the
20 /// most significant byte is on the right end of a word.
21 /// </remarks>
22 /// <returns>true if this converter is little-endian, false otherwise.</returns>
23 public abstract bool IsLittleEndian();
25 /// <summary>
26 /// Indicates the byte order ("endianess") in which data is converted using this class.
27 /// </summary>
28 public abstract Endianness Endianness { get; }
29 #endregion
31 #region Factory properties
32 static LittleEndianBitConverter little = new LittleEndianBitConverter();
33 /// <summary>
34 /// Returns a little-endian bit converter instance. The same instance is
35 /// always returned.
36 /// </summary>
37 public static LittleEndianBitConverter Little
39 get { return little; }
42 static BigEndianBitConverter big = new BigEndianBitConverter();
43 /// <summary>
44 /// Returns a big-endian bit converter instance. The same instance is
45 /// always returned.
46 /// </summary>
47 public static BigEndianBitConverter Big
49 get { return big; }
51 #endregion
53 #region Double/primitive conversions
54 /// <summary>
55 /// Converts the specified double-precision floating point number to a
56 /// 64-bit signed integer. Note: the endianness of this converter does not
57 /// affect the returned value.
58 /// </summary>
59 /// <param name="value">The number to convert. </param>
60 /// <returns>A 64-bit signed integer whose value is equivalent to value.</returns>
61 public long DoubleToInt64Bits(double value)
63 return BitConverter.DoubleToInt64Bits(value);
66 /// <summary>
67 /// Converts the specified 64-bit signed integer to a double-precision
68 /// floating point number. Note: the endianness of this converter does not
69 /// affect the returned value.
70 /// </summary>
71 /// <param name="value">The number to convert. </param>
72 /// <returns>A double-precision floating point number whose value is equivalent to value.</returns>
73 public double Int64BitsToDouble (long value)
75 return BitConverter.Int64BitsToDouble(value);
78 /// <summary>
79 /// Converts the specified single-precision floating point number to a
80 /// 32-bit signed integer. Note: the endianness of this converter does not
81 /// affect the returned value.
82 /// </summary>
83 /// <param name="value">The number to convert. </param>
84 /// <returns>A 32-bit signed integer whose value is equivalent to value.</returns>
85 public int SingleToInt32Bits(float value)
87 return new Int32SingleUnion(value).AsInt32;
90 /// <summary>
91 /// Converts the specified 32-bit signed integer to a single-precision floating point
92 /// number. Note: the endianness of this converter does not
93 /// affect the returned value.
94 /// </summary>
95 /// <param name="value">The number to convert. </param>
96 /// <returns>A single-precision floating point number whose value is equivalent to value.</returns>
97 public float Int32BitsToSingle (int value)
99 return new Int32SingleUnion(value).AsSingle;
101 #endregion
103 #region To(PrimitiveType) conversions
104 /// <summary>
105 /// Returns a Boolean value converted from one byte at a specified position in a byte array.
106 /// </summary>
107 /// <param name="value">An array of bytes.</param>
108 /// <param name="startIndex">The starting position within value.</param>
109 /// <returns>true if the byte at startIndex in value is nonzero; otherwise, false.</returns>
110 public bool ToBoolean (byte[] value, int startIndex)
112 CheckByteArgument(value, startIndex, 1);
113 return BitConverter.ToBoolean(value, startIndex);
116 /// <summary>
117 /// Returns a Unicode character converted from two bytes at a specified position in a byte array.
118 /// </summary>
119 /// <param name="value">An array of bytes.</param>
120 /// <param name="startIndex">The starting position within value.</param>
121 /// <returns>A character formed by two bytes beginning at startIndex.</returns>
122 public char ToChar (byte[] value, int startIndex)
124 return unchecked((char) (CheckedFromBytes(value, startIndex, 2)));
127 /// <summary>
128 /// Returns a double-precision floating point number converted from eight bytes
129 /// at a specified position in a byte array.
130 /// </summary>
131 /// <param name="value">An array of bytes.</param>
132 /// <param name="startIndex">The starting position within value.</param>
133 /// <returns>A double precision floating point number formed by eight bytes beginning at startIndex.</returns>
134 public double ToDouble (byte[] value, int startIndex)
136 return Int64BitsToDouble(ToInt64(value, startIndex));
139 /// <summary>
140 /// Returns a single-precision floating point number converted from four bytes
141 /// at a specified position in a byte array.
142 /// </summary>
143 /// <param name="value">An array of bytes.</param>
144 /// <param name="startIndex">The starting position within value.</param>
145 /// <returns>A single precision floating point number formed by four bytes beginning at startIndex.</returns>
146 public float ToSingle (byte[] value, int startIndex)
148 return Int32BitsToSingle(ToInt32(value, startIndex));
151 /// <summary>
152 /// Returns a 16-bit signed integer converted from two bytes at a specified position in a byte array.
153 /// </summary>
154 /// <param name="value">An array of bytes.</param>
155 /// <param name="startIndex">The starting position within value.</param>
156 /// <returns>A 16-bit signed integer formed by two bytes beginning at startIndex.</returns>
157 public short ToInt16 (byte[] value, int startIndex)
159 return unchecked((short) (CheckedFromBytes(value, startIndex, 2)));
162 /// <summary>
163 /// Returns a 32-bit signed integer converted from four bytes at a specified position in a byte array.
164 /// </summary>
165 /// <param name="value">An array of bytes.</param>
166 /// <param name="startIndex">The starting position within value.</param>
167 /// <returns>A 32-bit signed integer formed by four bytes beginning at startIndex.</returns>
168 public int ToInt32 (byte[] value, int startIndex)
170 return unchecked((int) (CheckedFromBytes(value, startIndex, 4)));
173 /// <summary>
174 /// Returns a 64-bit signed integer converted from eight bytes at a specified position in a byte array.
175 /// </summary>
176 /// <param name="value">An array of bytes.</param>
177 /// <param name="startIndex">The starting position within value.</param>
178 /// <returns>A 64-bit signed integer formed by eight bytes beginning at startIndex.</returns>
179 public long ToInt64 (byte[] value, int startIndex)
181 return CheckedFromBytes(value, startIndex, 8);
184 /// <summary>
185 /// Returns a 16-bit unsigned integer converted from two bytes at a specified position in a byte array.
186 /// </summary>
187 /// <param name="value">An array of bytes.</param>
188 /// <param name="startIndex">The starting position within value.</param>
189 /// <returns>A 16-bit unsigned integer formed by two bytes beginning at startIndex.</returns>
190 public ushort ToUInt16 (byte[] value, int startIndex)
192 return unchecked((ushort) (CheckedFromBytes(value, startIndex, 2)));
195 /// <summary>
196 /// Returns a 32-bit unsigned integer converted from four bytes at a specified position in a byte array.
197 /// </summary>
198 /// <param name="value">An array of bytes.</param>
199 /// <param name="startIndex">The starting position within value.</param>
200 /// <returns>A 32-bit unsigned integer formed by four bytes beginning at startIndex.</returns>
201 public uint ToUInt32 (byte[] value, int startIndex)
203 return unchecked((uint) (CheckedFromBytes(value, startIndex, 4)));
206 /// <summary>
207 /// Returns a 64-bit unsigned integer converted from eight bytes at a specified position in a byte array.
208 /// </summary>
209 /// <param name="value">An array of bytes.</param>
210 /// <param name="startIndex">The starting position within value.</param>
211 /// <returns>A 64-bit unsigned integer formed by eight bytes beginning at startIndex.</returns>
212 public ulong ToUInt64 (byte[] value, int startIndex)
214 return unchecked((ulong) (CheckedFromBytes(value, startIndex, 8)));
217 /// <summary>
218 /// Checks the given argument for validity.
219 /// </summary>
220 /// <param name="value">The byte array passed in</param>
221 /// <param name="startIndex">The start index passed in</param>
222 /// <param name="bytesRequired">The number of bytes required</param>
223 /// <exception cref="ArgumentNullException">value is a null reference</exception>
224 /// <exception cref="ArgumentOutOfRangeException">
225 /// startIndex is less than zero or greater than the length of value minus bytesRequired.
226 /// </exception>
227 static void CheckByteArgument(byte[] value, int startIndex, int bytesRequired)
229 if (value==null)
231 throw new ArgumentNullException("value");
233 if (startIndex < 0 || startIndex > value.Length-bytesRequired)
235 throw new ArgumentOutOfRangeException("startIndex");
239 /// <summary>
240 /// Checks the arguments for validity before calling FromBytes
241 /// (which can therefore assume the arguments are valid).
242 /// </summary>
243 /// <param name="value">The bytes to convert after checking</param>
244 /// <param name="startIndex">The index of the first byte to convert</param>
245 /// <param name="bytesToConvert">The number of bytes to convert</param>
246 /// <returns></returns>
247 long CheckedFromBytes(byte[] value, int startIndex, int bytesToConvert)
249 CheckByteArgument(value, startIndex, bytesToConvert);
250 return FromBytes(value, startIndex, bytesToConvert);
253 /// <summary>
254 /// Convert the given number of bytes from the given array, from the given start
255 /// position, into a long, using the bytes as the least significant part of the long.
256 /// By the time this is called, the arguments have been checked for validity.
257 /// </summary>
258 /// <param name="value">The bytes to convert</param>
259 /// <param name="startIndex">The index of the first byte to convert</param>
260 /// <param name="bytesToConvert">The number of bytes to use in the conversion</param>
261 /// <returns>The converted number</returns>
262 protected abstract long FromBytes(byte[] value, int startIndex, int bytesToConvert);
263 #endregion
265 #region ToString conversions
266 /// <summary>
267 /// Returns a String converted from the elements of a byte array.
268 /// </summary>
269 /// <param name="value">An array of bytes.</param>
270 /// <remarks>All the elements of value are converted.</remarks>
271 /// <returns>
272 /// A String of hexadecimal pairs separated by hyphens, where each pair
273 /// represents the corresponding element in value; for example, "7F-2C-4A".
274 /// </returns>
275 public static string ToString(byte[] value)
277 return BitConverter.ToString(value);
280 /// <summary>
281 /// Returns a String converted from the elements of a byte array starting at a specified array position.
282 /// </summary>
283 /// <param name="value">An array of bytes.</param>
284 /// <param name="startIndex">The starting position within value.</param>
285 /// <remarks>The elements from array position startIndex to the end of the array are converted.</remarks>
286 /// <returns>
287 /// A String of hexadecimal pairs separated by hyphens, where each pair
288 /// represents the corresponding element in value; for example, "7F-2C-4A".
289 /// </returns>
290 public static string ToString(byte[] value, int startIndex)
292 return BitConverter.ToString(value, startIndex);
295 /// <summary>
296 /// Returns a String converted from a specified number of bytes at a specified position in a byte array.
297 /// </summary>
298 /// <param name="value">An array of bytes.</param>
299 /// <param name="startIndex">The starting position within value.</param>
300 /// <param name="length">The number of bytes to convert.</param>
301 /// <remarks>The length elements from array position startIndex are converted.</remarks>
302 /// <returns>
303 /// A String of hexadecimal pairs separated by hyphens, where each pair
304 /// represents the corresponding element in value; for example, "7F-2C-4A".
305 /// </returns>
306 public static string ToString(byte[] value, int startIndex, int length)
308 return BitConverter.ToString(value, startIndex, length);
310 #endregion
312 #region Decimal conversions
313 /// <summary>
314 /// Returns a decimal value converted from sixteen bytes
315 /// at a specified position in a byte array.
316 /// </summary>
317 /// <param name="value">An array of bytes.</param>
318 /// <param name="startIndex">The starting position within value.</param>
319 /// <returns>A decimal formed by sixteen bytes beginning at startIndex.</returns>
320 public decimal ToDecimal (byte[] value, int startIndex)
322 // HACK: This always assumes four parts, each in their own endianness,
323 // starting with the first part at the start of the byte array.
324 // On the other hand, there's no real format specified...
325 int[] parts = new int[4];
326 for (int i=0; i < 4; i++)
328 parts[i] = ToInt32(value, startIndex+i*4);
330 return new Decimal(parts);
333 /// <summary>
334 /// Returns the specified decimal value as an array of bytes.
335 /// </summary>
336 /// <param name="value">The number to convert.</param>
337 /// <returns>An array of bytes with length 16.</returns>
338 public byte[] GetBytes(decimal value)
340 byte[] bytes = new byte[16];
341 int[] parts = decimal.GetBits(value);
342 for (int i=0; i < 4; i++)
344 CopyBytesImpl(parts[i], 4, bytes, i*4);
346 return bytes;
349 /// <summary>
350 /// Copies the specified decimal value into the specified byte array,
351 /// beginning at the specified index.
352 /// </summary>
353 /// <param name="value">A character to convert.</param>
354 /// <param name="buffer">The byte array to copy the bytes into</param>
355 /// <param name="index">The first index into the array to copy the bytes into</param>
356 public void CopyBytes(decimal value, byte[] buffer, int index)
358 int[] parts = decimal.GetBits(value);
359 for (int i=0; i < 4; i++)
361 CopyBytesImpl(parts[i], 4, buffer, i*4+index);
364 #endregion
366 #region GetBytes conversions
367 /// <summary>
368 /// Returns an array with the given number of bytes formed
369 /// from the least significant bytes of the specified value.
370 /// This is used to implement the other GetBytes methods.
371 /// </summary>
372 /// <param name="value">The value to get bytes for</param>
373 /// <param name="bytes">The number of significant bytes to return</param>
374 byte[] GetBytes(long value, int bytes)
376 byte[] buffer = new byte[bytes];
377 CopyBytes(value, bytes, buffer, 0);
378 return buffer;
381 /// <summary>
382 /// Returns the specified Boolean value as an array of bytes.
383 /// </summary>
384 /// <param name="value">A Boolean value.</param>
385 /// <returns>An array of bytes with length 1.</returns>
386 public byte[] GetBytes(bool value)
388 return BitConverter.GetBytes(value);
391 /// <summary>
392 /// Returns the specified Unicode character value as an array of bytes.
393 /// </summary>
394 /// <param name="value">A character to convert.</param>
395 /// <returns>An array of bytes with length 2.</returns>
396 public byte[] GetBytes(char value)
398 return GetBytes(value, 2);
401 /// <summary>
402 /// Returns the specified double-precision floating point value as an array of bytes.
403 /// </summary>
404 /// <param name="value">The number to convert.</param>
405 /// <returns>An array of bytes with length 8.</returns>
406 public byte[] GetBytes(double value)
408 return GetBytes(DoubleToInt64Bits(value), 8);
411 /// <summary>
412 /// Returns the specified 16-bit signed integer value as an array of bytes.
413 /// </summary>
414 /// <param name="value">The number to convert.</param>
415 /// <returns>An array of bytes with length 2.</returns>
416 public byte[] GetBytes(short value)
418 return GetBytes(value, 2);
421 /// <summary>
422 /// Returns the specified 32-bit signed integer value as an array of bytes.
423 /// </summary>
424 /// <param name="value">The number to convert.</param>
425 /// <returns>An array of bytes with length 4.</returns>
426 public byte[] GetBytes(int value)
428 return GetBytes(value, 4);
431 /// <summary>
432 /// Returns the specified 64-bit signed integer value as an array of bytes.
433 /// </summary>
434 /// <param name="value">The number to convert.</param>
435 /// <returns>An array of bytes with length 8.</returns>
436 public byte[] GetBytes(long value)
438 return GetBytes(value, 8);
441 /// <summary>
442 /// Returns the specified single-precision floating point value as an array of bytes.
443 /// </summary>
444 /// <param name="value">The number to convert.</param>
445 /// <returns>An array of bytes with length 4.</returns>
446 public byte[] GetBytes(float value)
448 return GetBytes(SingleToInt32Bits(value), 4);
451 /// <summary>
452 /// Returns the specified 16-bit unsigned integer value as an array of bytes.
453 /// </summary>
454 /// <param name="value">The number to convert.</param>
455 /// <returns>An array of bytes with length 2.</returns>
456 public byte[] GetBytes(ushort value)
458 return GetBytes(value, 2);
461 /// <summary>
462 /// Returns the specified 32-bit unsigned integer value as an array of bytes.
463 /// </summary>
464 /// <param name="value">The number to convert.</param>
465 /// <returns>An array of bytes with length 4.</returns>
466 public byte[] GetBytes(uint value)
468 return GetBytes(value, 4);
471 /// <summary>
472 /// Returns the specified 64-bit unsigned integer value as an array of bytes.
473 /// </summary>
474 /// <param name="value">The number to convert.</param>
475 /// <returns>An array of bytes with length 8.</returns>
476 public byte[] GetBytes(ulong value)
478 return GetBytes(unchecked((long)value), 8);
481 #endregion
483 #region CopyBytes conversions
484 /// <summary>
485 /// Copies the given number of bytes from the least-specific
486 /// end of the specified value into the specified byte array, beginning
487 /// at the specified index.
488 /// This is used to implement the other CopyBytes methods.
489 /// </summary>
490 /// <param name="value">The value to copy bytes for</param>
491 /// <param name="bytes">The number of significant bytes to copy</param>
492 /// <param name="buffer">The byte array to copy the bytes into</param>
493 /// <param name="index">The first index into the array to copy the bytes into</param>
494 void CopyBytes(long value, int bytes, byte[] buffer, int index)
496 if (buffer==null)
498 throw new ArgumentNullException("buffer", "Byte array must not be null");
500 if (buffer.Length < index+bytes)
502 throw new ArgumentOutOfRangeException("Buffer not big enough for value");
504 CopyBytesImpl(value, bytes, buffer, index);
507 /// <summary>
508 /// Copies the given number of bytes from the least-specific
509 /// end of the specified value into the specified byte array, beginning
510 /// at the specified index.
511 /// This must be implemented in concrete derived classes, but the implementation
512 /// may assume that the value will fit into the buffer.
513 /// </summary>
514 /// <param name="value">The value to copy bytes for</param>
515 /// <param name="bytes">The number of significant bytes to copy</param>
516 /// <param name="buffer">The byte array to copy the bytes into</param>
517 /// <param name="index">The first index into the array to copy the bytes into</param>
518 protected abstract void CopyBytesImpl(long value, int bytes, byte[] buffer, int index);
520 /// <summary>
521 /// Copies the specified Boolean value into the specified byte array,
522 /// beginning at the specified index.
523 /// </summary>
524 /// <param name="value">A Boolean value.</param>
525 /// <param name="buffer">The byte array to copy the bytes into</param>
526 /// <param name="index">The first index into the array to copy the bytes into</param>
527 public void CopyBytes(bool value, byte[] buffer, int index)
529 CopyBytes(value ? 1 : 0, 1, buffer, index);
532 /// <summary>
533 /// Copies the specified Unicode character value into the specified byte array,
534 /// beginning at the specified index.
535 /// </summary>
536 /// <param name="value">A character to convert.</param>
537 /// <param name="buffer">The byte array to copy the bytes into</param>
538 /// <param name="index">The first index into the array to copy the bytes into</param>
539 public void CopyBytes(char value, byte[] buffer, int index)
541 CopyBytes(value, 2, buffer, index);
544 /// <summary>
545 /// Copies the specified double-precision floating point value into the specified byte array,
546 /// beginning at the specified index.
547 /// </summary>
548 /// <param name="value">The number to convert.</param>
549 /// <param name="buffer">The byte array to copy the bytes into</param>
550 /// <param name="index">The first index into the array to copy the bytes into</param>
551 public void CopyBytes(double value, byte[] buffer, int index)
553 CopyBytes(DoubleToInt64Bits(value), 8, buffer, index);
556 /// <summary>
557 /// Copies the specified 16-bit signed integer value into the specified byte array,
558 /// beginning at the specified index.
559 /// </summary>
560 /// <param name="value">The number to convert.</param>
561 /// <param name="buffer">The byte array to copy the bytes into</param>
562 /// <param name="index">The first index into the array to copy the bytes into</param>
563 public void CopyBytes(short value, byte[] buffer, int index)
565 CopyBytes(value, 2, buffer, index);
568 /// <summary>
569 /// Copies the specified 32-bit signed integer value into the specified byte array,
570 /// beginning at the specified index.
571 /// </summary>
572 /// <param name="value">The number to convert.</param>
573 /// <param name="buffer">The byte array to copy the bytes into</param>
574 /// <param name="index">The first index into the array to copy the bytes into</param>
575 public void CopyBytes(int value, byte[] buffer, int index)
577 CopyBytes(value, 4, buffer, index);
580 /// <summary>
581 /// Copies the specified 64-bit signed integer value into the specified byte array,
582 /// beginning at the specified index.
583 /// </summary>
584 /// <param name="value">The number to convert.</param>
585 /// <param name="buffer">The byte array to copy the bytes into</param>
586 /// <param name="index">The first index into the array to copy the bytes into</param>
587 public void CopyBytes(long value, byte[] buffer, int index)
589 CopyBytes(value, 8, buffer, index);
592 /// <summary>
593 /// Copies the specified single-precision floating point value into the specified byte array,
594 /// beginning at the specified index.
595 /// </summary>
596 /// <param name="value">The number to convert.</param>
597 /// <param name="buffer">The byte array to copy the bytes into</param>
598 /// <param name="index">The first index into the array to copy the bytes into</param>
599 public void CopyBytes(float value, byte[] buffer, int index)
601 CopyBytes(SingleToInt32Bits(value), 4, buffer, index);
604 /// <summary>
605 /// Copies the specified 16-bit unsigned integer value into the specified byte array,
606 /// beginning at the specified index.
607 /// </summary>
608 /// <param name="value">The number to convert.</param>
609 /// <param name="buffer">The byte array to copy the bytes into</param>
610 /// <param name="index">The first index into the array to copy the bytes into</param>
611 public void CopyBytes(ushort value, byte[] buffer, int index)
613 CopyBytes(value, 2, buffer, index);
616 /// <summary>
617 /// Copies the specified 32-bit unsigned integer value into the specified byte array,
618 /// beginning at the specified index.
619 /// </summary>
620 /// <param name="value">The number to convert.</param>
621 /// <param name="buffer">The byte array to copy the bytes into</param>
622 /// <param name="index">The first index into the array to copy the bytes into</param>
623 public void CopyBytes(uint value, byte[] buffer, int index)
625 CopyBytes(value, 4, buffer, index);
628 /// <summary>
629 /// Copies the specified 64-bit unsigned integer value into the specified byte array,
630 /// beginning at the specified index.
631 /// </summary>
632 /// <param name="value">The number to convert.</param>
633 /// <param name="buffer">The byte array to copy the bytes into</param>
634 /// <param name="index">The first index into the array to copy the bytes into</param>
635 public void CopyBytes(ulong value, byte[] buffer, int index)
637 CopyBytes(unchecked((long)value), 8, buffer, index);
640 #endregion
642 #region Private struct used for Single/Int32 conversions
643 /// <summary>
644 /// Union used solely for the equivalent of DoubleToInt64Bits and vice versa.
645 /// </summary>
646 [StructLayout(LayoutKind.Explicit)]
647 struct Int32SingleUnion
649 /// <summary>
650 /// Int32 version of the value.
651 /// </summary>
652 [FieldOffset(0)]
653 int i;
654 /// <summary>
655 /// Single version of the value.
656 /// </summary>
657 [FieldOffset(0)]
658 float f;
660 /// <summary>
661 /// Creates an instance representing the given integer.
662 /// </summary>
663 /// <param name="i">The integer value of the new instance.</param>
664 internal Int32SingleUnion(int i)
666 this.f = 0; // Just to keep the compiler happy
667 this.i = i;
670 /// <summary>
671 /// Creates an instance representing the given floating point number.
672 /// </summary>
673 /// <param name="f">The floating point value of the new instance.</param>
674 internal Int32SingleUnion(float f)
676 this.i = 0; // Just to keep the compiler happy
677 this.f = f;
680 /// <summary>
681 /// Returns the value of the instance as an integer.
682 /// </summary>
683 internal int AsInt32
685 get { return i; }
688 /// <summary>
689 /// Returns the value of the instance as a floating point number.
690 /// </summary>
691 internal float AsSingle
693 get { return f; }
696 #endregion