Results 1 to 40 of 58

Thread: Creating User-Defined Types.

Threaded View

  1. #27
    Only Slightly Obsessive jemidiah's Avatar
    Join Date
    Apr 2002
    Posts
    2,431

    Re: Creating User-Defined Types.

    I saw this linked from the math forum. My own thoughts:

    This project has been done before a number of times. A brief search found http://sine.codeplex.com/ (amongst others just for .NET). Still, this type of project can be very educational and can also be fun. Certainly, if you're enjoying it, don't stop just because it's been done before. Just keep in mind when it is and isn't worth the time to reinvent the wheel.


    Ok, the responsible side of me has been satisfied well enough. Two formats have been proposed, and I have some of my own. I'll list them with pros and cons.

    1. A BigInt holding the integer part, and a BigInt holding the fractional part.
      • Pros: Mirrors how a human typically thinks about decimals.
      • Cons: You might be tempted to implement your own addition routine to deal with fractional addition (though this can be avoided by multiplying one of the addends by a suitable power of 10). Multiplication is a 4-part operation involving some tedious reasoning. I'm not immediately sure how division could be done.

    2. A single BigInt holding the mantissa, and another BigInt (well, I would use a BigInt) holding the exponent.
      • Pros: You don't have to split every calculation into pieces like with the above method. Multiplication is extremely easy. Addition does not have to be difficult either, as above.
      • Cons: Actually, I don't really see any. This is very similar to the format the IEEE settled on for floating point numbers, just with an arbitrary-length mantissa. It makes sense that it's a very good option. Come to think of it, division would be somewhat difficult.
      • Note: You might want to look in to a base 2 exponent rather than base 10. Multiplication by 2 is likely very fast on BigInts (and if it's not, it should be). If you do this, though, you'll have to convert to base 10 to display results.

    3. Arbitrary-precision rational numbers, using a BigInt for the numerator and another BigInt for the denominator.
      • Pros: Allows you to store rational numbers without loss of precision. Fundamentally, pretty much everything is built up from basic operations on rational numbers. Also, the Euclidean Algorithm is fast enough to allow you to cancel like terms from the numerator and denominator, keeping things small-ish and allowing you to implement equality testing trivially. Addition, subtraction, multiplication, and division are all simple extensions of the relevant BigInt operations, followed by canceling like terms.
      • Cons: The rational numbers involved can get huge. For practicality's sake you would probably have to implement a "round" routine which trimmed the denominator down to some specified size. That routine would be somewhat interesting to come up with. Also, the ToString() method would need a fair amount of work.

    4. This one is a bit advanced. Allow arbitrary-precision rationals, together with a set of definable symbols (eg. pi, e). An object would be some (finite) combination of rationals, symbols, and operations (+, -, /, *, etc.).
      • Pros: I imagine this is essentially what computer algebra systems use. It would be a wonderful exercise in recursively defined data types.
      • Cons: Of very questionable use without a computer algebra system behind the data type to perform simplifications automatically.


    There were a few other ideas I wanted to mention.

    First is an "exact" flag. A BigDecimal would start with exact = True. Whenever a BigDecimal is created through addition, multiplication, etc., if any rounding occurs whatsoever, exact gets set to False. exact = False propagates as well--adding an exact to an inexact value creates an inexact value. This would probably be most useful with rational numbers.

    Second, you may wish to allow the user to specify the precision of intermediate results in addition to the precision of a BigDecimal. Some operations may require several steps (eg. taking integer powers), and you should use more precision in those intermediate steps than actually required to prevent rounding errors from accumulating in the last few places.

    Third, if your numbers... actually, I forgot number three. Oh well. Edit: I remembered my point. Be careful about combining precision on different numbers. For instance, adding 37 and 1.0004 increases the precision in 37 to 4 digits after the decimal. Multiplication and division can be trickier.
    Last edited by jemidiah; Nov 22nd, 2011 at 07:41 PM.
    The time you enjoy wasting is not wasted time.
    Bertrand Russell

    <- Remember to rate posts you find helpful.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width