Grade Resolution

 hey is that you? I've released 12.1 so I couldn't reply. I'd like more than just integer values like Garmin does. But thinking maybe round it to the closest 0.5%? Think that might be better? I agree it is distracting to see the 0.1 resolution changing all the time.

  • Also, I realize this thought experiment has a flaw: the calculated grade is probably very unlikely to be exactly 2.5% (internally it's probably going to be something like 2.4998 or 2.5111, assuming that you're not doing any internal rounding), and this edge case only happens for an exact value of 2.5%.

    Nonetheless, it's a contrived example which is meant to show that a better rule might be to round when the grade is < 2.5%, and to show 1 decimal when the grade is >= 2.5%. That would eliminate the edge case mentioned above, even if it's not realistic in practice. (But again, is it practical to show 0.1% differences in grade?)

  • FYI In math round(2.5) = 2. So unless you tried this or there's a known bug that Garmin rounds 0.5 upwards, this is not a problem.

  • FYI In math round[2.5] = 2. So unless you tried this or there's a known bug that Garmin rounds 0.5 upwards, this is not a problem.

    Did you try it or read the docs? Have you ever used the standard round[] function in Excel, Google Sheets, C, Java, or JavaScript?

    In Monkey C, if Math.round[2.5] = 2, that would actually be a bug. It would not match Garmin's documented behavior.

    https://developer.garmin.com/connect-iq/api-docs/Toybox/Math.html#round-instance_function

    Returns:

    The closest integer to x. Decimal values >= .5 will be rounded up

    I didn't try it because I assumed the documentation is right, and because I've used Math.round in Monkey C before. But I'll try it now.

    Monkey C [simulator: fr935, fr955, and edge1050]:

    var float = 2.5f;
    var double = 2.5d;
    System.println[Math.round[float]]; // output: 3.000000
    System.println[Math.round[double]]; // output: 3.000000

    Real fr955, simple data field:

    function compute[] {
      return Math.round[2.5];
    }

    The output is 3.00.

  • BTW, many standard implementations (e.g. java, C) of round[] also round towards the nearest integer (half away from 0), just like Monkey C.

    Js is a little different, as it rounds towards +infinity when the fractional part is exactly 0.5 (which means -2.5 is rounded to -2), but it produces the same behavior for positive numbers as Java and C.

    Python 3 uses banker's rounding (half round even) but that doesn't seem to be what you described - you seemed to imply that all numbers ending in .5 should be rounded down or towards 0.

    FYI In math round[2.5] = 2

    What does "in math" mean here? Are you implying that "math" only has one way to round numbers?

    https://www.mathsisfun.com/rounding-numbers.html

    There are several different methods for rounding.

    https://www.mathsisfun.com/numbers/rounding-methods.html

    Even a math website aimed at literal kids describes 8 different methods of rounding (6 if you don't count floor and ceiling, which obviously have dedicated functions in most programming languages).

    If you want to argue that there's nonetheless a single standard, accepted, or common way to round numbers, then I would argue it's typically round to the nearest integer (half away from 0), as in Monkey C, C, and Java. But then again, banker's rounding exists for a reason (it's more numerically stable / less biased, which "minimizes the expected error when summing over rounded figures"). So there's at least 2 well-accepted ways to round numbers. And out of Java, javascript, C, and Python 3, there's 3 distinct implementations of the standard round function.

    Also, in Excel and Google Sheets, ROUND[2.5, 0] produces a result of 3. ROUND[-2.5, 0] => -3. It works just like Monkey C, C and Java (round to nearest integer, half away from 0). I'm sure Excel and Sheets users outnumber coders by a few orders of magnitude. So if you wanna argue from a pragmatic POV (what do normal ppl expect to see), round to nearest integer (half away from 0) is a de facto standard for rounding.

  • https://www.mathsisfun.com/numbers/rounding-methods.html

    Thanks for this link! I had no idea about all the things there are!

    Yes, math is fun! Thumbsup

  • I'lll try again.... I present an integer value until my GRADE calc returns >= 2.5% (or -2.5%). Then I report with a single decimal point of precision. So if my GRADE calc returns 2.6, I report 2.6. It if returns 2.45, I report 2. Hope that clears it up. The rounding only applies < 2.5.abs().

  • Thanks for the clarification!

    "The rounding only applies < 2.5.abs[]"

    That's absolutely not what you originally said:

    "I lock GRADE to 0% if <= 0.6, and in the screen I show a rounded integer when <=2.5%. Above 2.5% I currently show one decimal place."

    It follows from that statement that an exact value of 2.5 would be rounded, and that's the statement I originally replied to.

    You followed up with "If over that I use Math.round[].toNumber[] up to abs[] 2.5%". Normally when ppl say "up to", they mean "less than or equal to" (as opposed to "less than and not equal to")

    https://dictionary.cambridge.org/dictionary/english/up-to

    used to say that something is less than or equal to but not more than a stated value, number, or level:

    My main point was that in your system, the exact value of 2.5 shouldn't be rounded, otherwise the user would see some unexpected and misleading behaviour.

    I still think that it's an interesting choice to only round the value below some arbitrary absolute value (2.5). Personally I would go with always rounding to the nearest .5 or 1, but it's up to you.

  • Yeah I didn't like the 0.6 threshold to lock to 0%, so I reduced that to 0.4 in a later version. Also, I use a < 2.5 now not <= 2.5. Thanks! It would be extremely rare if ever for a floating point value to be exactly 2.5. But still, best to prevent that potential discontinuity.