Your Digital Media Has Never Looked So Good

 
agmark
Topic Author
Posts: 142
Joined: Thu Nov 10, 2011 8:29 am

Help with integers

Wed Feb 26, 2014 2:54 pm

I'm retrieving some json and parsing it. The items consist of an id, name and image. Not sure why but the id is not being parsed into an int. I'm getting data returned as follows when I print each item from the returned parsejson(raw):

name: Video
shortDescription: My video
thumbnailURL: http://...................../myimage.jpg
videos: <Component: roArray>
id:  3.171e+12


How do I handle the id and retrieve the correct integer? I'm attempting to print to the console but I'm not finding the solution. Probably something simple I'm missing.
 
User avatar
TheEndless
** Valued Community Member **
Posts: 9232
Joined: Mon Oct 04, 2004 10:15 am
Location: US
Contact:

Re: Help with integers

Wed Feb 26, 2014 3:44 pm

Most likely, the ID is a 64-bit integer in your JSON, which gets parsed as a float by Roku's ParseJSON function, often resulting in a completely different value. The only way I've found to work around it is to convert the values to strings before parsing. If you need it as an integer, then you can convert it back in BrightScript.

Here's the RegEx I use to convert any number in the JSON string that's nine digits or longer to a string:
regex = CreateObject("roRegex", ":(\s?)([0-9]{9,})", "")
newJson = regex.ReplaceAll(json,  ":\1" + Chr(34) + "\2" + Chr(34))
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
 
agmark
Topic Author
Posts: 142
Joined: Thu Nov 10, 2011 8:29 am

Re: Help with integers

Wed Feb 26, 2014 5:49 pm

That was it TheEndless! Thanks for helping. I was quickly losing my hear of that and I don't have as much to spare as I used to!
Many thanks.
 
EnTerr
** Valued Community Member **
Posts: 3834
Joined: Sun Jan 02, 2011 2:41 am

Re: Help with integers

Wed Feb 26, 2014 6:09 pm

TheEndless wrote:
Most likely, the ID is a 64-bit integer in your JSON, which gets parsed as a float by Roku's ParseJSON function, often resulting in a completely different value. The only way I've found to work around it is to convert the values to strings before parsing. If you need it as an integer, then you can convert it back in BrightScript.

Here's the RegEx I use to convert any number in the JSON string that's nine digits or longer to a string:
regex = CreateObject("roRegex", ":(\s?)([0-9]{9,})", "")
newJson = regex.ReplaceAll(json,  ":\1" + Chr(34) + "\2" + Chr(34))


Ha! That's a head-scratcher. It is worth mentioning that int`s are 32-bit in BS, no bignums and parseJSON() is behaving reasonably:
BrightScript Debugger> ? 2^30, 2^31, 2^32
 1073741824            -2147483648      0
BrightScript Debugger> l = parsejson("[999999999,9999999999]")
BrightScript Debugger> ? l
 999999999
 1e+10

BrightScript Debugger> ? type(l[0]), type(l[1])
Integer                Float

It will be best if JSON can be amended server-side, since the regex given will
  • miss cases where \t or multiple spaces are present between : and the number (in dictionary)
  • miss numbers within a list, e.g. [1, 1234567890, 3]
  • mangle strings that contain long numbers preceded by :, e.g. {"text": "this is how a 10-digit number looks like: 1234567890"}
 
User avatar
TheEndless
** Valued Community Member **
Posts: 9232
Joined: Mon Oct 04, 2004 10:15 am
Location: US
Contact:

Re: Help with integers

Wed Feb 26, 2014 7:49 pm

EnTerr wrote:
Ha! That's a head-scratcher. It is worth mentioning that int`s are 32-bit in BS, no bignums and parseJSON() is behaving reasonably:

Perhaps, but parsing as a Double instead of a Float seems to give better results. I recently had to overcome this in some JSON that had date/times in milliseconds, using this custom AsDouble() hack to convert the string after the regex replace...
Function AsDouble(input As Dynamic) As Double
    output# = 0
    If IsString(input) Then
        If input.Len() <= 9 Then
            output# = input.ToInt()
        Else
            ' Big string, so break it into parts and build the double
            low = input.Mid(input.Len() - 9, 9).ToInt()
            high = input.Mid(0, input.Len() - 9).ToInt()
            output# = high
            output# = output# * 1000000000
            output# = output# + low
        End If
    Else If IsInteger(input) Or IsFloat(input) Then
        output# = input
    End If
    Return output#
End Function

If you try to convert the string to a Float instead of a Double, you get completely different results (well, not completely, but different enough to cause a headache if you need accuracy).

EnTerr wrote:
miss cases where \t or multiple spaces are present between : and the number (in dictionary)

Oops. I tried to account for that, but mistakenly used "(\s?)" instead of "(\s*)". The regex should be:
:(\s*)([0-9]{9,})

EnTerr wrote:
  • miss numbers within a list, e.g. [1, 1234567890, 3]
  • mangle strings that contain long numbers preceded by :, e.g. {"text": "this is how a 10-digit number looks like: 1234567890"}

Good catch, and certainly worth mentioning as a caveat.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
 
EnTerr
** Valued Community Member **
Posts: 3834
Joined: Sun Jan 02, 2011 2:41 am

Re: Help with integers

Thu Feb 27, 2014 3:14 pm

TheEndless wrote:
Perhaps, but parsing as a Double instead of a Float seems to give better results. I recently had to overcome this in some JSON that had date/times in milliseconds, using this custom AsDouble() hack to convert the string after the regex replace...

B/S has separate float and double?! But there is no roString.toDouble()? Massaraksh!

Maybe you should try pushing (good luck!) for RokuCo to change parseJSON() to return doubles for numbers instead of floats. 4-byte floats have miserable precision, 6 significant digits (in a str->float->str flip) whereas double preserves 15 digits. Because of that I cannot think of a case in which float will be desirable from parseJSON(). Or ever :P
 
renojim
** Valued Community Member **
Posts: 3399
Joined: Mon Feb 15, 2010 1:35 pm

Re: Help with integers

Thu Feb 27, 2014 9:37 pm

In the past, when I've needed to convert a string representing a large integer into a Double I've used the following trick:
BrightScript Debugger> xstr="4294967296000"
BrightScript Debugger> eval("x="+xstr)
BrightScript Debugger> ?x
 4294967296000
BrightScript Debugger> ?type(x)
Double

-JT
 
User avatar
TheEndless
** Valued Community Member **
Posts: 9232
Joined: Mon Oct 04, 2004 10:15 am
Location: US
Contact:

Re: Help with integers

Thu Feb 27, 2014 9:57 pm

renojim wrote:
In the past, when I've needed to convert a string representing a large integer into a Double I've used the following trick:
BrightScript Debugger> xstr="4294967296000"
BrightScript Debugger> eval("x="+xstr)
BrightScript Debugger> ?x
 4294967296000
BrightScript Debugger> ?type(x)
Double

-JT

Nice trick! From what I've been told, though, using Eval() causes an inherent memory leak, so it should be avoided whenever possible. I can't imagine converting a handful of doubles via Eval would cause much of a problem, but still worth keeping in mind.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
 
renojim
** Valued Community Member **
Posts: 3399
Joined: Mon Feb 15, 2010 1:35 pm

Re: Help with integers

Fri Feb 28, 2014 3:15 am

TheEndless wrote:
From what I've been told, though, using Eval() causes an inherent memory leak, so it should be avoided whenever possible

I've wondered about that. I recall a test where I did an eval() in a loop and eventually the channel would crash. I guess the question is whether these leaks are cleaned up when the channel exits normally (or abnormally for that matter).

-JT
 
lukechinworth
Posts: 2
Joined: Mon Dec 17, 2018 3:39 pm

Re: Help with integers

Mon Dec 17, 2018 3:44 pm

I ended up doing
left(msTimeStamp, 10).toInt()

Who is online

Users browsing this forum: No registered users and 10 guests