2

Without using big int classes in C++, what's a good way to handle arithmetic on large numbers?

For instance, writing a Vector class that deals with dot products and cross products using large doubles can result in non-finite values. Do I leave this up to the user to handle NaN's/(-inf to inf), etc.? Or do I somehow handle those cases using std::isfinite within the Vector class (potentially modifying values within the class instance)? I feel kind of weird manipulating of a user created object if one or more of the resultant vector components is non-finite.

Input is appreciated.

  • What kind application? The answer will be different if you're programming a space probe vs. software to design landscaping plans – whatsisname Jul 13 '17 at 2:53
  • Does application really matter? As long as your user base understands intended behavior (usually by comments, good documentation - I'm using Doxygen), and good test procedures. I'm not talking about precision of numbers, moreso who should be responsible for handling numbers that end up outside acceptable ranges and enforcing it that behavior in other classes as well. – David Kramer Jul 13 '17 at 2:59
  • 3
    The application virtually always matters. For e.g. the landscaping example, encountering infinities is something that is just not ever going to happen, and not dealing with it may well be right thing to do, in making a worthwhile application for a reasonable cost. For a scientific application, handling astronomical calculations may be expected. – whatsisname Jul 13 '17 at 3:59
  • I understand that, but I'm not saying to ignore it based on application - I'm saying provide as much precision as possible while not harming a user's use of the class (by changing the values much). I'm not considering time and money to develop said class functionality (in this case they aren't dependent variables). Regardless of if the landscaping example won't normally encounter infinities, there are applications that may experience infinities. I'm trying to cover those outliers that will potentially hit infinities. – David Kramer Jul 13 '17 at 12:34
2

A generic "Vector" class is almost certainly not going to have the context to deal with such situations, and thus it should leave the data as-is. If by "user" you mean the programmer who is going to use your "Vector" class, then it's their responsibility to deal with such things. If you never expect these cases to occur due to the nature of application(s) using this class, then you could have the "Vector" signal an error, but I don't really recommend this and it doesn't sound like your use-case anyway. The most you should do as the implementer of the "Vector" class is to try to avoid unnecessarily producing non-finite values e.g. (a+b)/2 may be infinite where a/2 + b/2 might not be. (Of course, you may well also be concerned about underflow.) It may not be worth the extra code complexity and performance to do this though.

Whether the ultimate end-user should deal with this depends on what you expect of the user and whether some intermediate layer does have the context to meaningfully deal with this.

  • I think this is a pretty good answer in combination with @Doc Brown 's answer down below. The more I think about it, a generic Vector class doesn't have enough context to make that decision to be modifying values. Doc Brown mentioned potentially providing functionality that provides an easy way for the "user" to handle Vectors with NaN's (which essentially means it isn't really useful anymore). – David Kramer Jul 13 '17 at 12:41
1

I would follow the "principle of least astonishment".

If one creates a generic Vector class and wants to keep it universally, IMHO the most natural approach is to make its behaviour to overflows or underflows consistent with the behaviour of the underlying base type. So if you don't get an exception for an overflow using 64 bit doubles in the programming language of your choice, and the result ist just an NaN, a Vector based on doubles should show a similar behaviour. That means, if one component of the Vector becomes NaN, its probably best to interpret the whole vector as a "value which cannot be calculated with any more" (or an "NaV" = "Not a Vector", analoguesly to "NaN"= "Not a Number").

Consequently, one should provide a convenience function in the Vector class like IsNaV, which checks if all components are different from NaN, to give the user of the class a possibility to deal with this case more easily.

  • I may actually provide some sort of functionality to allow a "user" to determine if the Vector itself is still of finite values. To easily determine any of the arithmetic they performed caused non-finite values to occur. Thanks for the idea! – David Kramer Jul 13 '17 at 12:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.