diff --git a/django/utils/numberformat.py b/django/utils/numberformat.py
index 069f498..603ce1c 100644
--- a/django/utils/numberformat.py
+++ b/django/utils/numberformat.py
@@ -14,35 +14,45 @@ def format(number, decimal_sep, decimal_pos, grouping=0, thousand_sep=''):
 
     """
     use_grouping = settings.USE_L10N and \
-        settings.USE_THOUSAND_SEPARATOR and grouping
+        settings.USE_THOUSAND_SEPARATOR and grouping and thousand_sep
     # Make the common case fast:
     if isinstance(number, int) and not use_grouping and not decimal_pos:
         return mark_safe(unicode(number))
-    # sign
-    if float(number) < 0:
+    float_number = float(number)
+    if decimal_pos:
+        # Need to use %f format string, as unicode(number) can yield 
+        # exponents for sufficiently small numbers. As a bonus, we get
+        # rounding and right amount of decimal positions directly.
+        str_number = unicode(('%.' + str(decimal_pos) + 'f') % (num_number))
+    else:
+        # If decimal_pos is not given, use unicode(number), as %f will
+        # give 6 decimal positions even if the number doesn't have that
+        # many decimals.
+        str_number = unicode(number)
+    if 'e' in str_number:
+        # The number is either too small and no decimal_pos was given,
+        # or the number is too big. The number could be converted to 
+        # wanted format, but it is probably better to return it in
+        # exponent form (need for documentation?)
+        return str_number
+    if not use_grouping:
+        return str_number.replace('.', decimal_sep)
+    # Using grouping, need to separate sign, int_part, decimal part
+    if num_number < 0:
         sign = '-'
+        str_number = str_number[1:]
     else:
         sign = ''
-    str_number = unicode(number)
-    if str_number[0] == '-':
-        str_number = str_number[1:]
-    # decimal part
-    if '.' in str_number:
+    if decimal_pos or '.' in str_number:
         int_part, dec_part = str_number.split('.')
-        if decimal_pos:
-            dec_part = dec_part[:decimal_pos]
+        dec_part = decimal_sep + dec_part
     else:
         int_part, dec_part = str_number, ''
-    if decimal_pos:
-        dec_part = dec_part + ('0' * (decimal_pos - len(dec_part)))
-    if dec_part: dec_part = decimal_sep + dec_part
-    # grouping
-    if use_grouping:
-        int_part_gd = ''
-        for cnt, digit in enumerate(int_part[::-1]):
-            if cnt and not cnt % grouping:
-                int_part_gd += thousand_sep
-            int_part_gd += digit
-        int_part = int_part_gd[::-1]
-    return sign + int_part + dec_part
+    first_part_len = len(int_part) % grouping
+    full_parts = int_part[first_part_len:] 
+    groups = [full_parts[i:i+grouping] \
+        for i in range(0, len(full_parts), grouping)]
+    if first_part_len > 0:
+        groups.insert(0, int_part[0:first_part_len])
+    return sign + thousand_sep.join(groups) + dec_part
 
diff --git a/tests/regressiontests/i18n/tests.py b/tests/regressiontests/i18n/tests.py
index 4aa52b6..785b7ec 100644
--- a/tests/regressiontests/i18n/tests.py
+++ b/tests/regressiontests/i18n/tests.py
@@ -148,13 +148,15 @@ class FormattingTests(TestCase):
         """
         settings.USE_L10N = True
         settings.USE_THOUSAND_SEPARATOR = False
-        self.assertEqual(u'66666.66', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=','))
-        self.assertEqual(u'66666A6', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B'))
+        self.assertEqual(u'66666.67', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=','))
+        self.assertEqual(u'66666A7', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B'))
+        # ticket #14317
+        self.assertEqual(u'0,00', nformat(0.000000001, decimal_sep=',', decimal_pos=2))
 
         settings.USE_THOUSAND_SEPARATOR = True
-        self.assertEqual(u'66,666.66', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=','))
-        self.assertEqual(u'6B6B6B6B6A6', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B'))
-        self.assertEqual(u'-66666.6', nformat(-66666.666, decimal_sep='.', decimal_pos=1))
+        self.assertEqual(u'66,666.67', nformat(self.n, decimal_sep='.', decimal_pos=2, grouping=3, thousand_sep=','))
+        self.assertEqual(u'6B6B6B6B6A7', nformat(self.n, decimal_sep='A', decimal_pos=1, grouping=1, thousand_sep='B'))
+        self.assertEqual(u'-66666.7', nformat(-66666.666, decimal_sep='.', decimal_pos=1))
         self.assertEqual(u'-66666.0', nformat(int('-66666'), decimal_sep='.', decimal_pos=1))
         self.assertEqual(u'10000.0', nformat(self.l, decimal_sep='.', decimal_pos=1))
 
