|
|
Hi Guys,
I am getting many compile errors when using SafeInt with a double type, SafeInt<double> d(0.0)
Is SafeInt not designed to work with doubles/floats? Looking at the code it seems to handle conversions to and from doubles but I can not construct one using a double.
I am using 3.0.12p
Thanks
Glenn
|
|
Coordinator
Jan 27, 2010 at 8:31 PM
|
By design. It's Safe_Int_, not Safe_Float_. The compiler error you get should have pointed you to the class at the top of the file where we sort out what types you can make a SafeInt out of, in particular:
template<>
class NumericType<double>
{ public:
enum{ isBool =
false, isFloat =
true,
isInt = false
}; };
I've thought about making a SafeFloat, but floating point operations have entirely different classes of problems - mainly truncation. It is seriously non-trivial to detect this, and it is situational - the right answer isn't all that clear-cut. I could do
something like warn you that an operation had no effect, like adding a very large number to a small number, but for some code, that could be by design.
|
|
|
|
Hi David,
Thanks for providing this library, it is well thought out and very useful.
I did see that and can understand the issues around floating point math. I do have one concern regarding division. As you do support division how can we get accurate results without fully supporting doubles, 3 / 2 results in a double which is rounded, that
to me is not ideal.
Again, I think SafeInt is a very useful library I am just wondering about it's use in this case.
Thanks
Glenn
|
|
Coordinator
Jan 28, 2010 at 8:46 PM
|
In the C/C++ standard, integer division is a different animal than floating point, and it isn't as if someone wrote this:
int x, y, z;
x = (int)((float)y/(float(z));
It does the integer division directly, as can be seen from looking at the assembly. As to accuracy, it depends on what you're doing - for example:
(a * b) / c ?= (a / c) * b
This could be true or false, depending. In general, you want to do it like the left hand side. If you wanted to always round up, which is non-standard behavior, then you'd do something like
x = (int)ceil((double)y/(double)z);
|
|