4. Special Cases

4.1. Working with `doubles`

We are not talking about test doubles here, but about values of C/C++ `double` type (a.k.a double float.)

Cgreen is designed to make it easy and natural to write assertions and expectations. Many functions can be used for multiple data types, e.g. `is_equal_to()` applies to all integer type values, actually including pointers.

But the C language has its quirks. One of them is the fact that it is impossible to inspect the datatypes of values during run-time. This has e.g. forced the introduction of `is_equal_to_string()` to enable string comparisons.

4.1.1. Assertions and Constraints

When it comes to double typed values this has spilled over even further. For double typed values we have

 Constraint `is_equal_to_double(value)` `is_not_equal_to_double(value)` `is_less_than_double(value)` `is_greater_than_double(value)`

But there is also the special assert that you must use when asserting doubles

 Assertion `assert_that_double(expected, constraint)`

and the utility function

 Utility `significant_figures_for_assert_double_are(int figures)`

And of course they are designed to go together. So, if you want to assert an expression yeilding a `double` typed value, you need to combine them:

``````Ensure(Doubles, can_assert_double_values) {
significant_figures_for_assert_double_are(3);
assert_that_double(3.14, is_equal_to_double(5.0));
}``````
 You have to use `assert_that_double()` and `is_equal_to_double()` together.

and you would get

```double_tests.c:13: Failure: can_assert_double_values
Expected [3.14] to [equal double] [5.0] within  significant figures
actual value:			[3.140000]
expected value:			[5.000000]```

4.1.2. Mocks

The general mechanism Cgreen uses to transport values to and from mock functions is based on the simple idea that most types fit into a "large" integer and can be type converted to and from whatever type you need.

Since a `double float` will not fit into the same memory space as an integer Cgreen handles that by encapsulating ("boxing") the `double` into an area which is represented by the pointer to it. And that pointer can fit into the integer type value (`intptr_t`) that Cgreen uses to transport values into and out of `mock()`. To get the value back you "unbox" it.

There are two possible uses of `double` that you need to be aware of

1. When a parameter to the mocked function is of `double` type and needs to be matched in an constraint in an `expect` call.

2. When the mock function itself should return a `double` type value.

In the test you should use the special `double` type constraints and the `will_return_double()` convenience function. In the mock function you will have to take care to box and unbox as required.

 Boxing and unboxing in mock functions Description `box_double(double value)` Wrap the value in an allocated memory area and return a pointer to it `unbox_double(BoxedDouble *box)` Unwrap the value by freeing the area and returning the value

Here’s an example of that:

``````static double double_out(int i, double d) {
return unbox_double(mock(i, box_double(d))); (1)
}

Ensure(Doubles, can_be_arguments_to_mock_and_returned) {
expect(double_out,
when(i, is_equal_to(15)),
when(d, is_equal_to_double(31.32)), (2)
will_return_double(3.1415926));     (3)
assert_that_double(double_out(15, 31.32), is_equal_to_double(3.1415926));
}``````
 1 We can see that the parameter `d` to the mock function, since it is a `double`, it will have to be used as `box_double(d)` in the call to `mock()`. 2 The corresponding `expect()` uses a double constraint. 3 The mock function in this small example also returns a `double`. The `expect()` uses `will_return_double()` so the mock function needs to unbox the return value from `mock()` to be able to return the `double` type value.
 Strange errors may occur if you box and/or unbox or combine `double` constraints incorrectly.

4.1.3. Details of floating point comparison algorithm

The number of significant digits set with `significant_figures_for_assert_double_are()` specifies a relative tolerance. Cgreen considers two double precision numbers x and y equal if their difference normalized by the larger of the two is smaller than 10^(1 - significant_figures)^. Mathematically, we check that |x - y| < max(|x|, |y|) * 10^(1 - significant_figures)^.

Well documented subtleties arise when comparing floating point numbers close to zero using this algorithm. The article Comparing Floating Point Numbers, 2012 Edition by Bruce Dawson has an excellent discussion of the issue. The essence of the problem can be appreciated if we consider the special case where y == 0. In that case, our condition reduces to |x| < |x| * 10^(1 - significant_figures)^. After cancelling |x| this simplifies to 1 < 10^(1 - significant_figures)^. But this is only true if significant_figures < 1. In words this can be summarized by saying that, in a relative sense, all numbers are very different from zero. To circumvent this difficulty we recommend to use a constraint of the following form when comparing numbers close to zero:

``assert_that(fabs(x - y) < abs_tolerance);``

4.2. Using Cgreen with C++

The examples in this guide uses the C langauge to shows how to use CGreen. You can also use CGreen with C++.

 The following needs expansion and more details as the support for C++ is extended.

All you have to do is

• Use the `cgreen` namespace by adding `using namespace cgreen;` at the beginning of the file with your tests

There is also one extra feature when you use C++, the `assert_throws` function.

 If you use the runner, as described in [runner], and thus link your tests into a shared library, don’t forget to link it with the same C++ library that was used to create the `cgreen-runner`.