diff --git a/pycgtool/bondset.py b/pycgtool/bondset.py
index 11f0dc706bc420707672c7e6f1995db41935a376..a6f6f7b3e207472c75f166108e6b9f097506a597 100644
--- a/pycgtool/bondset.py
+++ b/pycgtool/bondset.py
@@ -345,30 +345,29 @@ class BondSet:
             bond.boltzmann_invert(temp=self._temperature,
                                   angle_default_fc=self._angle_default_fc)
 
-    def dump_values(self, target_number=100000):
+    def dump_values(self, target_number=10000):
         """
         Output measured bond values to files for length, angles and dihedrals.
 
         :param target_number: Approx number of sample measurements to output.  If None, all samples will be output
         """
 
+        def write_bonds_to_file(bonds, filename):
+            with open(filename, "w") as f:
+                for row in transpose_and_sample((bond.values for bond in bonds), n=target_number):
+                    print((len(row) * "{:12.5f}").format(*row), file=f)
+
         for mol in self._molecules:
             if mol == "SOL":
                 continue
-            with open("{0}_length.dat".format(mol), "w") as f:
-                bonds = self.get_bond_lengths(mol, with_constr=True)
-                for row in transpose_and_sample((bond.values for bond in bonds), n=target_number):
-                    print((len(row) * "{:12.5f}").format(*row), file=f)
+            bonds = self.get_bond_lengths(mol, with_constr=True)
+            write_bonds_to_file(bonds, "{0}_length.dat".format(mol))
 
-            with open("{0}_angle.dat".format(mol), "w") as f:
-                bonds = self.get_bond_angles(mol)
-                for row in transpose_and_sample((bond.values for bond in bonds), n=target_number):
-                    print((len(row) * "{:12.5f}").format(*row), file=f)
+            bonds = self.get_bond_angles(mol)
+            write_bonds_to_file(bonds, "{0}_angle.dat".format(mol))
 
-            with open("{0}_dihedral.dat".format(mol), "w") as f:
-                bonds = self.get_bond_dihedrals(mol)
-                for row in transpose_and_sample((bond.values for bond in bonds), n=target_number):
-                    print((len(row) * "{:12.5f}").format(*row), file=f)
+            bonds = self.get_bond_dihedrals(mol)
+            write_bonds_to_file(bonds, "{0}_dihedral.dat".format(mol))
 
     def __len__(self):
         return len(self._molecules)
diff --git a/pycgtool/util.py b/pycgtool/util.py
index c1acccebe21afccd9204a1d0249c66effa0c250e..3624529ed710121cfa14c217212b1570c80812e6 100644
--- a/pycgtool/util.py
+++ b/pycgtool/util.py
@@ -6,6 +6,7 @@ import os
 import itertools
 import random
 import math
+import filecmp
 
 import numpy as np
 np.seterr(all="raise")
@@ -307,3 +308,47 @@ def gaussian(xs, mean=0, sdev=1, amplitude=1):
         top_bit = (x - mean) * (x - mean) / (2 * sdev * sdev)
         return prefactor * np.exp(-top_bit)
     return map(gaussian_single, xs)
+
+
+def cmp_whitespace_float(ref_filename, test_filename, float_rel_error=0.01):
+    """
+    Compare two files ignoring spacing on a line and using a tolerance on floats
+
+    :param ref_filename: Name of reference file
+    :param test_filename: Name of test file
+    :param float_rel_error: Acceptable relative error on floating point numbers
+    :return: True if files are the same, else False
+    """
+    def float_or_string(string):
+        try:
+            int(string)
+            return string
+        except ValueError:
+            try:
+                return float(string)
+            except ValueError:
+                return string
+
+    if filecmp.cmp(ref_filename, test_filename):
+        return True
+    with open(ref_filename) as ref_file, open(test_filename) as test_file:
+        for ref_line, test_line in itertools.zip_longest(ref_file, test_file):
+            if ref_line is None or test_line is None:
+                return False
+            if ref_line == test_line:
+                continue
+
+            ref_toks = ref_line.split()
+            test_toks = test_line.split()
+            if len(ref_toks) != len(test_toks):
+                return False
+            for ref_tok, test_tok in zip(map(float_or_string, ref_toks),
+                                         map(float_or_string, test_toks)):
+                if ref_tok != test_tok:
+                    if float == type(ref_tok) and float == type(test_tok):
+                        if abs(ref_tok - test_tok) > ref_tok * float_rel_error:
+                            return False
+                    else:
+                        return False
+    return True
+
diff --git a/test/test_bondset.py b/test/test_bondset.py
index 5028dc810c13f64c326ca95ec9733c0ec052cc97..14f7ce22bdd2383a026df25a7f61983e0dc5867e 100644
--- a/test/test_bondset.py
+++ b/test/test_bondset.py
@@ -1,9 +1,9 @@
 import unittest
-import filecmp
 
 from pycgtool.bondset import BondSet
 from pycgtool.frame import Frame
 from pycgtool.mapping import Mapping
+from pycgtool.util import cmp_whitespace_float
 
 
 class DummyOptions:
@@ -118,4 +118,4 @@ class BondSetTest(unittest.TestCase):
         measure.boltzmann_invert()
         measure.write_itp("sugar_out.itp", mapping, exclude={"SOL"})
 
-        self.assertTrue(filecmp.cmp("sugar_out.itp", "test/data/sugar_out.itp"))
+        self.assertTrue(cmp_whitespace_float("sugar_out.itp", "test/data/sugar_out.itp", float_rel_error=0.001))