   C++ math lib - error : return value or exception?
  I'm writing a math library. It will contain classes like Line, Ray, Circle, Rectangle, Triangle, Polygon etc. One of its goals is to be very fast.The Line class represents a 2D line and has member functions to help the programmer.Line: aX + bY + c = 0struct Line{float a, b, c;Line(float _a, float _b, float _c);Line(const Vec2 &point, float gradient);Line(const Vec2 &point1, const Vec2 &point2);bool operator == (const Line &r1) const;// if gradient is equal to infinity, INFINITY is returnedfloat Gradient() const; // = -a/b// angle with X axisfloat Angle() const;float GetX(float y) const;float GetY(float x) const;};Let's consider GetX():GetX() returns a x offset based on the line.e.g: line: y = 5x + 10: GetX(0) will return -2But if the line's type is y = 5 ( 0X + 1Y - 5 = 0),there will be an error (because there are infinite x offsets)Which version of GetX() would you recommend?float Line::GetX(float y) const{if( a ) return (- b / a) * y - (c / a);throw std::out_of_range("Line's type is \"bY + c = 0\". x doesn't exist.");}float Line::GetX(float y) const{if( a ) return (- b / a) * y - (c / a);return INFINITY;}The 1st one throws an exception with a meaningful message, but is slower; the 2nd returns a value indicating the mistake. The value can be ignored though, but the function is faster.   
  why not just return floating point infinity for those values?   ;Quote:Original post by ibebrettwhy not just return floating point infinity for those values?INFINITY is defined FLT_MAX (max value of float)   ;  In my math library I return std::numeric_limits< float >::infinity( ) for failed intersection tests. They can happen fairly often so I think exceptions are too heavy-weight there.   ;Quote:Original post by sheep19INFINITY is defined FLT_MAX (max value of float)Yikes. Why? Infinity and FLT_MAX are very different things.   ;Quote:Original post by SneftelQuote:Original post by sheep19INFINITY is defined FLT_MAX (max value of float)Yikes. Why? Infinity and FLT_MAX are very different things.Because FLT_MAX is the max value of float so I thought it would be a good idea to set INFINITY to it...Wrong?   ;  Floating point values have explicit values that represent positive and negative infinity. Just like any other number, including FLT_MAX, infinities are unique  values.   ;  The difference between FLT_MAX and infinity is that infinity / 2 == infinity, whereas FLT_MAX / 2 != FLT_MAX. Infinity is a very special value to the standard floating point representation. Now, it's not necessarily a hugely useful value to you. Any such value you return will just be used to signal a problem. So I would suggest the special floating point value which is explicitly designed for signalling a problem: NaN. NaNs behave pretty much like you'd want them to: You can check for them, and math done with them will indicate that the results are a problem. (For instance, if you decided to divide a number by the result of GetX() and it returned infinity, you'd silently end up with a 0, whereas if GetX returned NaN, the result of the division will also be a NaN.more info;  This is one of those problems where the question is incorrect.Just because line is horizontal, and has infinite number of X values, there is no problem. At any given angle, there are infinite number of coordinates as well.The real solution takes into consideration what this line will be used for. aX+bY+c=0 represents every line, even vertical and horizontal ones.How will I use this in, say, collision detection of UI elements, where all lines are vertical or horizontal anyway.And lines represented in this form will suffer from accuracy problems. Imagine polygon defined using these. 3 lines forming a triangle created from points in (A,B,C) will suffer from accuracy errors, meaning they will never intersect exactly at (A,B,C). This causes considerable complications when trying to manipulate anything non-trivial.Specifying line as a pair of points solves this problem.Quote:One of its goals is to be very fast.The biggest gains by far will come from elsewhere. As long as one is dealing with individual lines it simply doesn't matter. To truly improve upon processing rates, all lines would be processed at once. For example:vector<Line> lines;vector<Line>::iterator i = std::partition(lines.begin(), lines.end(), IsHorizontal);processNonHorizontalLines(lines.begin(), i);processHorizontalLines(i, lines.end);Even though this incurs an extra pass over all lines (which can be implemented differently if needed), it quickly overtakes as far as processing goes, can be done in parallel, and requires no error handling.   ;  Thanks a lot for the replies:OK I understand the problem with FLT_MAX. I changed my constants:#include "sml_constants.h"#include <limits>namespace sml{const float INFINITY = std::numeric_limits <float>::infinity(),NOT_NUMBER = std::numeric_limits<float>::quiet_NaN();}For some values I'm using INFINITY, for other NOT_NUMBER.float Line::Gradient() const{if( b ) return -a/b;return INFINITY;}float Line::GetX(float y) const{if( a ) return (- b / a) * y - (c / a);return NOT_NUMBER;}float Line::GetY(float x) const{if( b ) return Gradient() * x - (c / b);return NOT_NUMBER;}