This project is read-only.

SafeInt with double

Jan 27, 2010 at 2:54 PM

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



Jan 27, 2010 at 9: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.


Jan 28, 2010 at 8:46 AM

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.



Jan 28, 2010 at 9: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);