Michael Rys

Musings on XML, XQuery and more...

<July 2008>
SuMoTuWeThFrSa
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789


Navigation

Papers

SQL Server XML Whitepapers

Weblogging Links

MS Bloggers

Recommended Books

Other Blogs

Recommended Links

Presentations (Upcoming)

Presentations (Recent)

Subscriptions

News


Upcoming Presentations


TechEd 2007, Orlando, June 4 to June 8, 2007


Books I co-authored



www.flickr.com
This is a Flickr badge showing public photos from Michael Rys. Make your own badge here.
eXTReMe Tracker

Post Categories

Article Categories



CLR UDT Example: ComplexNumber.cs

 System;
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using System.Globalization;

/*=====================================================================

  File:      ComplexNumber.cs
  Summary:   A Format.Native UDT that represents a complex number
  Date:      Sep 23, 2003

---------------------------------------------------------------------

  This file is part of the Microsoft SQL Server Code Samples.
  Copyright (C) Microsoft Corporation.  All rights reserved.

This source code is intended only as a supplement to Microsoft
Development Tools and/or on-line documentation.  See these other
materials for detailed information regarding Microsoft code samples.

THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

======================================================= */
namespace Microsoft.Samples.SqlServer
{

    [Serializable]
    [SqlUserDefinedType(Format.Native, IsByteOrdered = true)]
    [System.Xml.Serialization.XmlSerializerAssemblyAttribute("ComplexNumber.XmlSerializers, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null")]
    public struct ComplexNumber : INullable, IComparable
    {
        //Regular expression used to parse values that are of the form (1,2i)
        private static readonly Regex _parser = new Regex(@"\(\s*(?<real>\-?\d+(\.\d+)?)\s*,\s*(?<img>\-?\d+(\.\d+)?)\s*i\s*\)", RegexOptions.Compiled | RegexOptions.ExplicitCapture);

        double _r;

        double _i;

        bool _isnull;

        const string NULL = "<<null complex>>";

        static readonly ComplexNumber NULL_INSTANCE = new ComplexNumber(true);


        public ComplexNumber(double r, double i)
        {
            _r = r;
            _i = i;
            _isnull = false;
        }


        private ComplexNumber(bool isnull)
        {
            _isnull = isnull;
            _r = _i = 0;
        }


        public double Real
        {
            get
            {
                if (_isnull)
                    throw new InvalidOperationException();

                return _r;
            }
            set { _r = value; }
        }


        public double Imaginary
        {
            get
            {
                if (_isnull)
                    throw new InvalidOperationException();

                return _i;
            }
            set { _i = value; }
        }


        public double Modulus
        {
            get
            {
                if (_isnull)
                    throw new InvalidOperationException();

                return Math.Sqrt(_r * _r + _i * _i);
            }
        }

        #region value-based equality
        public int CompareTo(object o)
        {
            if (!(o is ComplexNumber))
                return -1;

            ComplexNumber c = (ComplexNumber)o;

            if (_isnull && c._isnull)
                return 0;

            if (_isnull || c._isnull)
                return -1;

            if (_r == c._r && _i == c._i)
                return 0;

            if (Modulus == c.Modulus) // same modulus but different r/i, force diff
                return -1;

            // arbitrary comparison...semantics for complex numbers not necessarily correct
            return Modulus.CompareTo(c.Modulus);
        }

        public override bool Equals(object o)
        {
            return this.CompareTo(o) == 0;
        }

        public override int GetHashCode()
        {
            return Modulus.GetHashCode();
        }

        public static SqlBoolean operator ==(ComplexNumber c1, ComplexNumber c2)
        {
            return c1.Equals(c2);
        }

        public static SqlBoolean operator !=(ComplexNumber c1, ComplexNumber c2)
        {
            return !c1.Equals(c2);
        }

        public static SqlBoolean operator <(ComplexNumber c1, ComplexNumber c2)
        {
            return c1.CompareTo(c2) < 0;
        }
        public static SqlBoolean operator >(ComplexNumber c1, ComplexNumber c2)
        {
            return c1.CompareTo(c2) > 0;
        }

        #endregion

        public override string ToString()
        {
            return _isnull ? NULL : ("(" + _r + "," + _i + "i)");
        }


        public bool IsNull
        {
            get { return _isnull; }
        }


        public static ComplexNumber Parse(SqlString s)
        {
            string value = s.ToString();

            if (NULL == value)
                return new ComplexNumber(true);

            Match m = _parser.Match(value);

            if (!m.Success)
                throw new ArgumentException("Invalid format for complex number. Format is ( n, mi ) where n and m are floating point numbers");

            return new ComplexNumber(double.Parse(m.Groups[1].Value, CultureInfo.InvariantCulture), double.Parse(m.Groups[2].Value, CultureInfo.InvariantCulture));
        }


        public static ComplexNumber Null
        {
            get { return NULL_INSTANCE; }
        }
    }
}

posted on Tuesday, April 12, 2005 12:30 PM by mrys





Powered by Dot Net Junkies, by Telligent Systems