printfn / fend

Arbitrary-precision unit-aware calculator
https://printfn.github.io/fend
MIT License
587 stars 50 forks source link

Adding percentages gives counterintuitive results #264

Open printfn opened 5 months ago

printfn commented 5 months ago

Originally posted by @sergeevabc in https://github.com/printfn/fend/issues/164#issuecomment-1902457446.

The percentage calculation here is quite strange.

$ fend 90+10%
90.1

---

$ qalc 90+10%
90 * (110 * percent) = 99

$ kalker 90+10%
99

$ https://www.wolframalpha.com/input?i=90%2B10%25
99

$ https://www.symbolab.com/solver/step-by-step/90%2B10%5C%25?or=input
99

Windows 7 calculator

flexibeast commented 2 months ago

i'm guessing the "point_one_plus_five_percent" test has probably contributed to this. It's:

fn point_one_plus_five_percent() {
    test_eval("0.1 + 5%", "0.15");
}

However, on the basis of your opening comment for this issue, "0.1 + 5%" should be interpreted as "0.1 plus (5% of 0.1)", i.e. "0.1 plus 0.005" = "0.105", not "0.15".

Fwiw, that interpretation seems reasonable to me. More generally, though, i'm not sure that some other percentage-related tests behave as i intuitively expect:

#[test]
fn five_percent_plus_point_one() {
    test_eval("5% + 0.1", "0.15");
}

#[test]
fn five_percent_plus_one() {
    test_eval("5% + 1", "1.05");
}

Again working on the basis of the example provided in this issue's initial comment, it looks like the unit of the first value determines how the second value should act on it. In this context, i expected the first test to result in an output of "5.1%", and the output of the second to be "6%".

Not that my intuition in this regard is necessarily correct! i'm probably thinking in terms of "basis points", and it might be that you'll need to decide how to handle such scenarios (possibly simply by documenting the interpretation you're using).

bgkillas commented 1 month ago

probably should just make x-y% parse as x(1-y*0.01), still probably has odd edge cases