Adds two DDValue numbers using error-free transformations to maintain extra precision. It carefully adds the high parts, computes the rounding error, adds the low parts along with the error, and then normalizes the result.
(&mut self, a: DDValue, b: DDValue)
| 863 | /// It carefully adds the high parts, computes the rounding error, adds the low parts along with the error, |
| 864 | /// and then normalizes the result. |
| 865 | fn dd_add(&mut self, a: DDValue, b: DDValue) -> DDValue { |
| 866 | // Compute the sum of the high parts. |
| 867 | let s = self.builder.ins().fadd(a.hi, b.hi); |
| 868 | // Compute t = s - a.hi to capture part of the rounding error. |
| 869 | let t = self.builder.ins().fsub(s, a.hi); |
| 870 | // Compute the error e from the high part additions. |
| 871 | let s_minus_t = self.builder.ins().fsub(s, t); |
| 872 | let part1 = self.builder.ins().fsub(a.hi, s_minus_t); |
| 873 | let part2 = self.builder.ins().fsub(b.hi, t); |
| 874 | let e = self.builder.ins().fadd(part1, part2); |
| 875 | // Sum the low parts along with the error. |
| 876 | let lo = self.builder.ins().fadd(a.lo, b.lo); |
| 877 | let lo_sum = self.builder.ins().fadd(lo, e); |
| 878 | // Renormalize: add the low sum to s and compute a new low component. |
| 879 | let hi_new = self.builder.ins().fadd(s, lo_sum); |
| 880 | let hi_new_minus_s = self.builder.ins().fsub(hi_new, s); |
| 881 | let lo_new = self.builder.ins().fsub(lo_sum, hi_new_minus_s); |
| 882 | DDValue { |
| 883 | hi: hi_new, |
| 884 | lo: lo_new, |
| 885 | } |
| 886 | } |
| 887 | |
| 888 | /// Subtracts DDValue b from DDValue a by negating b and then using the addition function. |
| 889 | fn dd_sub(&mut self, a: DDValue, b: DDValue) -> DDValue { |
no test coverage detected