From: Joey Hess Date: Fri, 30 Jul 2021 13:56:04 +0000 (-0400) Subject: Fix a rounding bug in display of data sizes X-Git-Tag: archive/raspbian/10.20250416-2+rpi1~1^2~91^2~13 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=66089e97de6d40cf6cf7f464628f42521d0a0bf6;p=git-annex.git Fix a rounding bug in display of data sizes Eg, showImprecise 1 1.99 returned "1.1" rather than "2". The 9 rounded upward to 10, and that was wrongly used as the decimal, rather than carrying the 1. Sponsored-by: Jack Hill on Patreon --- diff --git a/CHANGELOG b/CHANGELOG index aa0e3a79b8..44d25e8e77 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -22,6 +22,7 @@ git-annex (8.20210715) UNRELEASED; urgency=medium * Fix bug that could prevent pointer files from being populated, in a repository that was upgraded from v7. * fsck: Detect and correct stale or missing inode caches. + * Fix a rounding bug in display of data sizes. -- Joey Hess Wed, 14 Jul 2021 14:26:36 -0400 diff --git a/Utility/HumanNumber.hs b/Utility/HumanNumber.hs index 6143cef105..04a18b0be0 100644 --- a/Utility/HumanNumber.hs +++ b/Utility/HumanNumber.hs @@ -1,6 +1,6 @@ {- numbers for humans - - - Copyright 2012-2013 Joey Hess + - Copyright 2012-2021 Joey Hess - - License: BSD-2-clause -} @@ -11,11 +11,15 @@ module Utility.HumanNumber (showImprecise) where - of decimal digits. -} showImprecise :: RealFrac a => Int -> a -> String showImprecise precision n - | precision == 0 || remainder == 0 = show (round n :: Integer) - | otherwise = show int ++ "." ++ striptrailing0s (pad0s $ show remainder) + | precision == 0 || remainder' == 0 = show (round n :: Integer) + | otherwise = show int' ++ "." ++ striptrailing0s (pad0s $ show remainder') where int :: Integer (int, frac) = properFraction n remainder = round (frac * 10 ^ precision) :: Integer + (int', remainder') + -- carry the 1 + | remainder == 10 ^ precision = (int + 1, 0) + | otherwise = (int, remainder) pad0s s = replicate (precision - length s) '0' ++ s striptrailing0s = reverse . dropWhile (== '0') . reverse diff --git a/doc/bugs/git-annex_info_rounding_error.mdwn b/doc/bugs/git-annex_info_rounding_error.mdwn index 4fa5d3271c..0ad7393fd8 100644 --- a/doc/bugs/git-annex_info_rounding_error.mdwn +++ b/doc/bugs/git-annex_info_rounding_error.mdwn @@ -45,3 +45,5 @@ All remotes above sit on 2tb disk drives, which are filled as much as possible. Thank you for all your time creating and maintaining such a usefull software! + +> [[fixed|done]] --[[Joey]] diff --git a/doc/bugs/git-annex_info_rounding_error/comment_1_37079e9f024b048fb0074683f9037d19._comment b/doc/bugs/git-annex_info_rounding_error/comment_1_37079e9f024b048fb0074683f9037d19._comment new file mode 100644 index 0000000000..4c4578416b --- /dev/null +++ b/doc/bugs/git-annex_info_rounding_error/comment_1_37079e9f024b048fb0074683f9037d19._comment @@ -0,0 +1,70 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 1""" + date="2021-07-30T12:59:46Z" + content=""" +I am confused by the output you show, because 2147483647 is not any number +of terabytes. It is a couple of gigabytes. This makes me suspect you +arrived at that number in some mistaken way. + +Also, when git-annex displays "TB", it's talking about TeraBytes, not +TebiBytes (TiB). But your divisions by 1024 is calulating the latter, not the +former. (Well, actually it's calculating gibibytes..) + +If there is a bug, it's presumably in Utility.HumanNumber.showImprecise, +which does some tricky rounding of decimals. + +Here's a few simple tests: + + # ghci Utility/DataUnits.hs + ghci> roughSize storageUnits True 1000000000000 + "1 TB" + ghci> roughSize storageUnits True 1099511627776 + "1.1 TB" + +Those are the correct results for an even terabyte and a tebibyte, +displayed as terabytes. Now trying the number you provided to see what +git-annex info will display: + + ghci> roughSize storageUnits True 2147483647 + "2.15 GB" + +units confirms that is the correct value, after rounding the decimal: + + # units + You have: 2147483647 bytes + You want: gigabytes + * 2.1474836 + / 0.46566129 + +aIt's also almost exactly 2 gibibytes: + + You have: 2147483647 bytes + You want: gibibytes + * 2 + / 0.5 + +The actual value is 1 byte less than 2, if I do my manual math correctly: + 2^30*2 = 2147483648 = 2147483647+1 + +Asking git-annex for the same using memoryUnits which are the SI units: + + ghci> roughSize memoryUnits False 2147483647 + "1.1 gibibytes" + +Well, this final result looks wrong, and indeed what's going on is +similar to what you hypothesized: + + ghci> roughSize' memoryUnits False 10 2147483647 + "1.9999999991 gibibytes" + ghci> showImprecise 10 1.9999999990686774 + "1.9999999991" + ghci> showImprecise 2 1.9999999990686774 + "1.1" + ghci> round 0.9999999990686774 * (10^2) + 100 + +So indeed showImprecise is forgetting to carry the 1. + +Excellent diagnosis, but next time, show your work. ;-) +"""]]