PaddiM8 / kalker

Scientific calculator with math syntax that supports user-defined variables and functions, complex numbers, and estimation of derivatives and integrals
https://kalker.xyz
MIT License
1.63k stars 73 forks source link

Configure result appearance #160

Open omniwrench opened 4 days ago

omniwrench commented 4 days ago

Hi. First off, this is a very nice program. Thanks for making and sharing it.

I would like to be able to configure how the end result is displayed. It would it nice if a config could be set to do so.

Currently, kalker displays results in the following manner.

> kalker 'sqrt(72)'
≈ 8.4852813742 ≈ √72

> kalker 'sqrt(72) + (5 * sqrt(26))'
≈ 33.9803789422

I would like to be able to specify that I want the exact result displayed first, and the approximation afterwards. This might also prevent this strange situation where the sqrt(72) I give as input is shown as approximately equal to √72. I also want to be able to factor out perfect squares, so √72 becomes 6 * √2. Lastly, I would also like to be able to modify how the multiplication symbol looks. kalker (at least the web version uses the dot operator (U+22C5). qalc on the other hand uses the multiplication sign × (U+00D7). I would like to be able to choose between options for this. And the mode I'd prefer would likely be implied multiplication i.e. √72 = 6√2, for more complex results, brackets could be used for clarity but skipped for simpler results.

qalc output for comparison:

> qalc 'sqrt(72)'
sqrt(72) = 6 × √(2) ≈ 8.485281374

> qalc 'sqrt(72) + (5 * sqrt(26))'
sqrt(72) + (5 × sqrt(26)) = 5 × √(26) + 6 × √(2) ≈ 33.98037894

My preferred output form:

> kalker 'sqrt(72)'
= 6√2 ≈ 8.485281374

> kalker 'sqrt(72) + (5 * sqrt(26))'
= 5√26 + 6√2 ≈ 33.98037894

A further improvement would be being able to specify approximate results should be on a separate line.

> kalker 'sqrt(72)'
= 6√2
≈ 8.485281374

> kalker 'sqrt(72) + (5 * sqrt(26))'
= 5√26 + 6√2
≈ 33.98037894

At least for me, these look much cleaner. I'll look into seeing if I can contribute this change myself if you agree this feature is useful.

PaddiM8 commented 3 days ago

The reason for the current order is that the non-numerical results often are approximations themselves. For example, if you manually type 8.48528137, it's going to tell you that it's approximately sqrt72. In cases like this, I think it makes sense to place the numerical result first to show that it's the primary result. In other cases, where it's an exact result, it would make sense to place it first. However, I feel like it could be confusing if the order changes, so I'm not sure.

With something like this:

>> 1/2 + 1/3
≈ 0.8333333333 = 5/6

It would be clearer to present it as = 5/6 ≈ 0.833333333 instead... Hmm, so I guess it would make sense to have an option that makes it display the exact result first, regardless of if that's a number or a symbolic expression

omniwrench commented 3 days ago

Huh. I did as you said

> kalker '8.48528137'
= 8.48528137 ≈ √72

That's... interesting. Is such a characteristic desirable though? I mean if I put in an arbitrary non-integer number, I'm not sure how useful it is to me to be told that it is approximately equal to the square root of some other random number.

I could maybe see someone wanting to know which is the closest square root to some arbitrary non-integer number, but to make these approximations/comparisons by default seems a bit strange to me. I'm not aware of any other calculator that does this.

Using qalc for comparison again, I can see that it doesn't try to infer any other information from an arbirary non-integer that I give it, like which square root is it approximately equal to.

$ qalc
> sqrt(72)

  sqrt(72) = 6 × √(2) ≈ 8.485281374

> 8.485281374

  8.485281374 = 8 + 242640687/500000000

And on a tangent, I'm curious how this is working in kalker under the hood. Is there a small list of numbers hard-coded in the program itself so it immediately recognizes what number is approximately equal to sqrt(72). Seems unlikely. Does it crunch through a list of numbers until it finds a number who's square root matches the given non-integer. Also seems unlikely and probably too computationally intensive. Does it just cache previous results so that when I previously calculated sqrt(72) it just stored the approximation and matched it later when I typed in 8.48...?

PaddiM8 commented 3 days ago

It does this to be able to show you more descriptive results regardless of which steps you take to calculate it, without having to embed an entire complex CAS that can solve anything you give to it symbolically. With square roots it's quite simple since it can just square it and check if the result is an integer. With things like fractions, it uses some slightly more involved algorithms, but still quite simple, to figure it out. With constants it mostly just looks them up in a dictionary. Typically, you'd need a reaaally specific number to get the square root estimate, so pretty much in 99.9% of cases it's relevant, and when it's not, it doesn't hurt since it's still a true statement.

I think it is desirable, because it allows kalker to be much smaller and simpler than eg. WolframAlpha while still offering some of the functionality for a lot of use-cases in a really consistent way. The alternative would be to always just solve it symbolically, but then you wouldn't be able to rely on it giving you this information, since it realistically wouldn't be able to solve any expression you give to it symbolically. For example, now I could do something involved like Σ(n=1, 2, ∫(0, 2, 1/(sqrt2) dx)) and it can still easily figure out that the result is sqrt8, which qalc doesn't seem to for me at least, but even if it does it must have added a lot of complexity to the implementation. It's a compromise, but it ensures that kalker can keep being the smaller and simpler little brother of eg. WolframAlpha