diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f703f74b..47e657ed 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -8,21 +8,31 @@ Unreleased Fixed ^^^^^ -* Fixed bugs where values were incorrectly rounded when - ``pdg_sig_figs`` was used with 0 or non-finite uncertainty. - Previously, if the value was positive it would possibly be rounded - incorrectly. - Now the value will be rounded under the same rules as ``AutoDigits``. - Previously, if the value was zero or negative a spurious exception - would be raised. - Now the value/uncertainty pair is formatted correctly without raising - and exception. +* Fixed a bug where bracket uncertainties erroneously appeared as + empty parentheses for zero or non-finite uncertainties. + [`#66 `_] +* Fixed a bug where the exponent value was erroneously calculated + from the uncertainty rather than the value when the value was + negative (but larger in magnitude than the uncertainty). + [`#68 `_] +* Fixed a bug where certain leading digits were erroneously not + stripped from the uncertainty when using bracket uncertainty with + negative values. + [`#68 `_] +* Fixed a bug where the value was erroneously being rounded + according to the PDG rounding rules when ``pdg_sig_figs=True``, + the uncertainty was zero or non-finite, and the value was + positive. [`#71 `_] +* Fixed a bug where a spurious error was raised when + ``pdg_sig_figs=True``, the uncertainty was zero or non-finite, and + the value was zero or negative. + [`#65 `_] Changed ^^^^^^^ -* Replace `-e .` with `.` in `requirements.txt`. There is no need to - install `sciform` in editable mode for code automation routines. +* Replace ``-e .`` with ``.`` in ``requirements.txt``. There is no need + to install ``sciform`` in editable mode for code automation routines. ---- diff --git a/src/sciform/format_utils.py b/src/sciform/format_utils.py index d00ac0af..11a04212 100644 --- a/src/sciform/format_utils.py +++ b/src/sciform/format_utils.py @@ -253,7 +253,7 @@ def get_pdg_round_digit(num: Decimal) -> int: # Bring num to be between 100 and 1000. num_top_three_digs = num * Decimal(10) ** (Decimal(2) - Decimal(top_digit)) - num_top_three_digs = round(num_top_three_digs, 0) + num_top_three_digs.quantize(1) new_top_digit = get_top_digit(num_top_three_digs) num_top_three_digs = num_top_three_digs * 10 ** (2 - new_top_digit) if 100 <= num_top_three_digs <= 354: diff --git a/src/sciform/formatting.py b/src/sciform/formatting.py index 558e90c5..379f3012 100644 --- a/src/sciform/formatting.py +++ b/src/sciform/formatting.py @@ -161,7 +161,7 @@ def format_val_unc(val: Decimal, unc: Decimal, else: round_driver = val ''' - Don't use pdg sig figs if the uncertainty doesn't drive the number of + Don't use pdg sig figs if the uncertainty doesn't drive the number of sig figs. ''' use_pdg_sig_figs = False @@ -202,7 +202,7 @@ def format_val_unc(val: Decimal, unc: Decimal, exp_mode = ExpMode.FIXEDPOINT if val.is_finite() and unc.is_finite(): - if val >= unc: + if abs(val) >= unc: exp_driver = val_rounded val_exp_driver = True else: @@ -296,7 +296,9 @@ def format_val_unc(val: Decimal, unc: Decimal, val_unc_str = f'{val_str}{pm_symb}{unc_str}' else: if unc.is_finite() and val.is_finite(): - if unc < val: + if unc == 0: + unc_str = '0' + elif unc < abs(val): unc_str = unc_str.lstrip('0.,_ ') if options.bracket_unc_remove_seps: unc_str = unc_str.replace( diff --git a/tests/test_val_unc_formatter.py b/tests/test_val_unc_formatter.py index 732a2d0f..55c7f913 100644 --- a/tests/test_val_unc_formatter.py +++ b/tests/test_val_unc_formatter.py @@ -41,6 +41,27 @@ def test_bracket_unc(self): self.run_val_unc_formatter_cases(cases_list) + def test_bracket_unc_invalid_unc(self): + cases_list = [ + ((123, 0), [ + (FormatOptions(bracket_unc=True), '123(0)') + ]), + ((-123, 0), [ + (FormatOptions(bracket_unc=True), '-123(0)') + ]), + ((123, float('nan')), [ + (FormatOptions(bracket_unc=True), '123(nan)') + ]), + ((123, float('inf')), [ + (FormatOptions(bracket_unc=True), '123(inf)') + ]), + ((0, 0), [ + (FormatOptions(bracket_unc=True), '0(0)') + ]), + ] + + self.run_val_unc_formatter_cases(cases_list) + def test_prefix(self): cases_list = [ ((123.456, 0.789), [ @@ -239,12 +260,11 @@ def test_pdg_invalid_unc(self): ]), ((0, float('nan')), [ (FormatOptions(pdg_sig_figs=True), '0 +/- nan') - ]), + ]) ] self.run_val_unc_formatter_cases(cases_list) - def test_binary_not_implemented(self): sform = Formatter(FormatOptions(exp_mode=ExpMode.BINARY)) self.assertRaises(NotImplementedError, sform, 1024, 32) diff --git a/tests/test_val_unc_fsml.py b/tests/test_val_unc_fsml.py index f201fac8..255c8055 100644 --- a/tests/test_val_unc_fsml.py +++ b/tests/test_val_unc_fsml.py @@ -30,6 +30,14 @@ def test_fixed(self): ('!4f', '123.4560 +/- 0.7890'), ('!2f()', '123.46(79)') ]), + ((-123.456, 0.789), [ + ('f', '-123.456 +/- 0.789'), + ('!1f', '-123.5 +/- 0.8'), + ('!2f', '-123.46 +/- 0.79'), + ('!3f', '-123.456 +/- 0.789'), + ('!4f', '-123.4560 +/- 0.7890'), + ('!2f()', '-123.46(79)') + ]), ((0.789, 123.456), [ ('f', '0.789 +/- 123.456'), ('!1f', '0 +/- 100'), @@ -46,7 +54,24 @@ def test_fixed(self): ('!5f()', '0.79(123.46)'), ('!6f()', '0.789(123.456)'), ('!7f()', '0.7890(123.4560)') - ]) + ]), + ((-0.789, 123.456), [ + ('f', '-0.789 +/- 123.456'), + ('!1f', '0 +/- 100'), + ('!2f', '0 +/- 120'), + ('!3f', '-1 +/- 123'), + ('!4f', '-0.8 +/- 123.5'), + ('!5f', '-0.79 +/- 123.46'), + ('!6f', '-0.789 +/- 123.456'), + ('!7f', '-0.7890 +/- 123.4560'), + ('!1f()', '0(100)'), + ('!2f()', '0(120)'), + ('!3f()', '-1(123)'), + ('!4f()', '-0.8(123.5)'), + ('!5f()', '-0.79(123.46)'), + ('!6f()', '-0.789(123.456)'), + ('!7f()', '-0.7890(123.4560)') + ]) ] self.run_val_unc_fsml_cases(cases_list) @@ -181,6 +206,31 @@ def test_bracket_unc(self): ('ex+1()', '(12.3456(789))e+01'), ('ex-1()', '(1234.56(7.89))e-01'), ]), + ((-123.456, 0.789), [ + ('()', '-123.456(789)'), + ('e()', '(-1.23456(789))e+02'), + ('r()', '(-123.456(789))e+00'), + ('#r()', '(-0.123456(789))e+03'), + ('ex+1()', '(-12.3456(789))e+01'), + ('ex-1()', '(-1234.56(7.89))e-01'), + ]), + ((0.789, 123.456), [ + ('()', '0.789(123.456)'), + ('e()', '(0.00789(1.23456))e+02'), + ('r()', '(0.789(123.456))e+00'), + ('#r()', '(0.000789(0.123456))e+03'), + ('ex+1()', '(0.0789(12.3456))e+01'), + ('ex-1()', '(7.89(1234.56))e-01') + ]), + ((-0.789, 123.456), [ + ('()', '-0.789(123.456)'), + ('e()', '(-0.00789(1.23456))e+02'), + ('r()', '(-0.789(123.456))e+00'), + ('#r()', '(-0.000789(0.123456))e+03'), + ('ex+1()', '(-0.0789(12.3456))e+01'), + ('ex-1()', '(-7.89(1234.56))e-01') + + ]), ((123456.654321, 0.000002), [ (',._!1f()', '123,456.654_321(2)') ])