[Mono-list] Fw: FW: System.Data.SqlTypes.SqlDecimal

Tim Coleman tim@timcoleman.com
Wed, 8 May 2002 00:07:21 -0400

Begin forwarded message:

Date: Wed, 8 May 2002 00:07:33 -0400
From: "Tim Coleman" <tcoleman@opentext.com>
To: <tim@timcoleman.com>
Subject: FW: System.Data.SqlTypes.SqlDecimal

-----Original Message-----
From: Tim Coleman [mailto:tcoleman@opentext.com]
Sent: Tuesday, May 07, 2002 8:48 PM
To: mono-list@ximian.com
Subject: System.Data.SqlTypes.SqlDecimal

I have an issue with the System.Data.SqlTypes.SqlDecimal structure.
It would seem that the appropriate internal representation would
be to store the value as a decimal.  There's just one problem with
this: decimals are 96 bit values while SqlDecimals can be 128 bit.

Importantly, there are two constructors for SqlDecimal that take
arrays of four integers representing the 128 bit value.  I've noticed,
that even on .NET, if you pass in a value with the high 32 bits set
to anything, you will get an OverflowException when you try to do
things like get the Value of it.  However, what doesn't make sense
is that you can actually write the value out to the console (!).
What I would like to know is how this data is stored and displayed
if you can't fit it into a decimal.  It's clear that MS does not 
store it in a decimal, because you would get an overflow immediately.
I could see that if the upper 32 bits are zero, then you could create
the decimal cleanly using the first 96 bits.. but anyway, here's some
code that I ran on CSC.  You can't run it on linux because I haven't
got that part of the class library done yet (because of this problem).

using System;
using System.Data.SqlTypes;

	class MainApp {
		public static void Main ()
			int[] bits = new int[4];
			bits[0] = 1;
			bits[1] = 1;
			bits[2] = 1;
			bits[3] = 1;
			byte bPrecision = 38;
			byte bScale = 10;
			bool fPositive = true;

			SqlDecimal x = new SqlDecimal (bPrecision, bScale, fPositive, bits);

			// works correctly
			System.Console.WriteLine (x);
			// throws an exception
			try {
				System.Console.WriteLine (x.Value);
			} catch (OverflowException e) {
				System.Console.WriteLine (e.Message);

			bits[0] = 1;
			bits[1] = 1;
			bits[2] = 1;
			bits[3] = 0;

			x = new SqlDecimal (bPrecision, bScale, fPositive, bits);
			// works fine
			System.Console.WriteLine (x.Value);

HMS Division, Open Text Corporation
Tim Coleman <tcoleman@opentext.com>; Telephone: +1 519 888 7111 ext. 2619
"The man who trades freedom for security does not deserve 
nor will he ever receive either. " -- Benjamin Franklin

Tim Coleman <tim@timcoleman.com>                       [43.28 N 80.31 W]
BMath, Honours Combinatorics and Optimization, University of Waterloo
 "They that can give up essential liberty to obtain a little temporary
  safety deserve neither liberty nor safety." -- Benjamin Franklin