Locale Linux: challenge with double and periods

I have encountered a strange issue. Let’s assume I have defined a double.

Var percentage as double = 10.05

This will show up perfectly fine in my browser, when run locally on macOS. After deployment it will show on Ubuntu as 1005.

Now I can of course do something like:

if TargetLinux then
  percentage = percentage / 100
end if

And this actually works (showing 10.05 in my app on Ubuntu), but it doesn’t feel to be right.

I assume it is somehow related to the locale, but I can define a locale for a double, can I? I’m confused, sorry.

Is the value actually one thousand and five or is this just a display issue?

I assume it is as display error, but as I can’t debug on the live server I don’t know yet how to test this. I believe it must be something with period and comma (so locale settings).

Do some math on it and log that?

If myDouble.Equals(10.05,4) then
//log it
Else
// log it
End if
1 Like
var myDouble as double = 1234.5
var myDouble2 as double
myDouble2 = myDouble / 2.3

messageBox( myDouble.ToString + " | " + myDouble2.ToString )

looking good on both systems:

macOS

webServer

Thank you for you help. It seems to be related to my JSONs and/or CURL somehow running differently locally or when run from the remote server. I have to dive into that deeper.

You are using jsonitem?

no, MBS plugin for both cURL and JSON

Maybe the json mbs does something to it?

Getting closer to it. The MBS plugins are not the root cause. I found the same “behavior” in a part of code, where I’m reading directly from a postgres Database. I’m using the same remote Database when debugging locally and when the code is running on the server. Locally I have an SSH connection to connect to the remote database.

This code

var items(-1) as string
items = iDrive.split( chr(9) )
var percentage as double = items(3).left(items(3).Length - 1).ToDouble
messageBox( percentage.ToString)

is showing on macOS locally:

but on the remote Ubuntu Box it pops up as:

Here is where I’m struggling:

I changed the “debugging test code” to the following:

var items(-1) as string
items = iDrive.split( chr(9) )
var test as integer = items(3).length
messageBox( test.ToString + " | " + items(3) )
var percentage as double = items(3).left(items(3).Length - 1).ToDouble

I would have expected that there is something wrong with the period in the percentage (74,93%), but running the above code locally, I do get:

and remotely:

So the issue seems to be in the conversion routine to double … as both variables are identical locally and remote.

try

Var double As String = items(3).Replace(",", "").left(items(3).Length - 1).ToDouble

It could be something (maybe a comma) that is parsing badly ?
Or maybe the encoding is not correct ?

  • What is the actual Locale (string) on the Server side ?
LANG=de_DE.UTF-8
LANGUAGE=
LC_CTYPE="de_DE.UTF-8"
LC_NUMERIC=de_DE.UTF-8
LC_TIME="de_DE.UTF-8"
LC_COLLATE="de_DE.UTF-8"
LC_MONETARY="de_DE.UTF-8"
LC_MESSAGES=de_DE.utf8
LC_PAPER="de_DE.UTF-8"
LC_NAME="de_DE.UTF-8"
LC_ADDRESS="de_DE.UTF-8"
LC_TELEPHONE="de_DE.UTF-8"
LC_MEASUREMENT="de_DE.UTF-8"
LC_IDENTIFICATION="de_DE.UTF-8"

But behaves identically with LC_NUMERIC numeric being set to en_US.UTF-8. I suspect the “,” in the “74,93%” string, but I am surprised that

var test as integer = items(3).length
messageBox( test.ToString + " | " + items(3) )

is showing the same result locally and remote. So it can’t be the encoding, can it?

i suspect a bug here. it seems very odd that parsing moves the “.” 2 points to the right.
It could be that the .Length is different ?

var items(-1) as string
items = iDrive.split( chr(9) )
var percentage as double = items(3).left(items(3).Length - 1).ToDouble
messageBox( percentage.ToString)

Can you log (on the server):

  • items(3).Length ?
  • items(3) the value ?
  • the percentage (as string) ?

Those combined in a messagebox and a screenshot should show an issue i guess.

var testStr as string = items(3)
var testLength as integer = items(3).length
var percentage as double = items(3).left(items(3).Length - 1).ToDouble
var percentStr as string = percentage.ToString
var percentlength as integer = percentStr.length
messageBox( testStr + "|" + testLength.ToString + "|" + percentStr + "|" + percentlength.tostring )

locally:

remote:

lenght is different… That’s your issue.
Not sure if this is a bug, but i could be encoding …

Try to

var testStr as string = items(3)
testStr = testStr.DefineEncoding(Encodings.UTF8)
var testLength as integer = items(3).length
var pre_double As String = items(3).left(items(3).Length - 1)
var percentage as double = pre_double.ToDouble
var percentStr as string = percentage.ToString
var percentlength as integer = percentStr.length
messageBox( testStr + "|" + pre_double + "|" + testLength.ToString + "|" + percentStr + "|" + percentlength.tostring )

Try the above, it will output the actual string before it parses it to a double.

Please show the output of both platforms
It’s ofcourse normal that the length shows longer since there are two additional “00” in the string.
I see the base string lenght is “6” which is both correct. Not sure where to go here.

Same output as above, it is not the encoding :-(. Funny enough (when replacing the comma by a period, it doesn’t change the overall behavior either). I added a Replace-Statement:

var percentage as double = items(3).replaceAll(",",".").left(items(3).Length - 1).ToDouble

Local result:

Remote result:

I don’t think it’s bug, but most likely me - others would have noted this I guess … must be something terribly simple and stupid …

But I really hate code like:

if TargetLinux then
  percentage = percentage / 100
end if

That solves the “issues”, but I believe it is just wrong doing that without knowing what the issue is.

Thank you very much for your example code:

var testStr as string = items(3)
testStr = testStr.DefineEncoding(Encodings.UTF8)
var testLength as integer = items(3).length
var pre_double As String = items(3).left(items(3).Length - 1)
var percentage as double = pre_double.ToDouble
var percentStr as string = percentage.ToString
var percentlength as integer = percentStr.length
messageBox( testStr + "|" + pre_double + "|" + testLength.ToString + "|" + percentStr + "|" + percentlength.tostring )

Here are the results:

locally:

remote:

so, the pre_double is looking good, weird.

I still suspect the SSH connection (locally) versus running the webApp remotely, but I don’t know how to debug that or how to tackle this problem. This is the code bit for the SSH connection:

Var cmd As String = "ssh -o ConnectTimeout=15 MyConnectionStr -L 5432:127.0.0.1:5432 -N -v &"
sshshell.Execute(cmd)

I think this is a bug in the linux .ToString extention for Double values… That would cause serious problems. @Greg_O_Lone care to verfify if this could be the cause?

@Jeannot_Muller could you try .Val instead of .ToDouble ?

From the docs:

For localized number formatting, use the ToDouble function instead. Generally, you will use Val for converting internal data and use ToDouble for converting data for input and output of user data.

1 Like

Indeed! That’s why I’m so curious to know. It seems BTW to be the same for currency conversion. I was only too shy probably: as a user of non US regional formats you are getting used to conversion issues and most of the time it is my fault, but this one really drives me nuts.