nicklockwood / Expression

A cross-platform Swift library for evaluating mathematical expressions at runtime
MIT License
830 stars 51 forks source link

Trying to evaluate when the region of the device is set to french #14

Open jmserrato opened 6 years ago

jmserrato commented 6 years ago

Hi, I'm trying to evaluate a basic expression, like this one 2+3.5 so if I have the region set to some other country that the comma is the decimal separator, the method evaluate is throwing the error, not sure if there is a way to set the decimal separator thanks in advance, you did a really great work with this library

nicklockwood commented 6 years ago

@jmserrato hmm, good catch. I didn't really consider localization.

nicklockwood commented 6 years ago

@jmserrato I'm not sure I understand what you mean by "evaluate is throwing the error".

The expression "2+3.5" seems to work correctly if your region is set to French.

Are you saying that you would expect it to also work if you wrote "2+3,5" instead?

It looks like Apple's Calculator app on iOS supports using either 2+3.5 or 2+3,5 when the locale is set to French, and Google supports using either format regardless of your device locale and uses some kind of heuristic to work out what you meant.

I could possibly add an option to set the decimal separator, although that would put the burden on the developer to work out which one to use based on the current locale. I guess another option would be to take a locale parameter and infer the decimal separator from that.

I wouldn't want to infer it automatically from the current device locale, or use a heuristic like Google, because that would introduce ambiguity, and possibly cause working code to break in different locales.

nicklockwood commented 6 years ago

I'm not sure how function like pow(4,5) would work if , was being used as the decimal separator. Do you know how this is normally handled in French apps?

I'm assuming programming language IDEs like Xcode are not locale-aware, but what about Excel, or other apps that let you type formulae?

zmeyc commented 6 years ago

@nicklockwood I can't say for French, but with Russian locale Excel uses comma (,) as decimal separators and ; for separating arguments, I believe it's 'List separator' in Windows Locale options, not sure where it takes it from on OS X. So, =POWER(3.14,4) becomes =POWER(3,14;4).

Excel uses system locale separators by default, but this can be overridden in Settings: https://www.howtogeek.com/245510/how-to-change-excels-decimal-separators-from-periods-to-commas/

Imo it would be ideal if the lib would allow setting custom separators (with reasonable default like the current ones) and opt-in into using locale-aware ones.

p.s. the lib and the docs are simply awesome! Very intuitive to use.

AegerBorder commented 4 years ago

What @zmeyc said is valid for Germany, too. I've played around with NumberFormatter the last days. Presenting the result als a formatted String is simple (see below) but to make it accept expressions with a comma as decimal separator instead of a point seems to be impossible so far.

Just to present the formatted result to EU decimal:

let formatter = NumberFormatter()
let expression = Expression("23.5+23.29")

result = try expression.evaluate()

// Just a few examples
formatter.numberStyle = .decimal
formatter.decimalSeparator = ","
formatter.groupingSeparator = "."
formatter.roundingMode = .ceiling
formatter.maximumFractionDigits = 15

outputTextField.stringValue = formatter.string(from: NSNumber(value: result)) ?? "0" // 46,79 instead of 46.79

It would be so great if this sweet piece of ingenious expression handler could be compatible with the european decimal "rules".