Roku Developer Program

Developers and content creators—a complete solution for growing an audience directly.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Level 7

Help with integers

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.
0 Kudos
9 Replies
Highlighted
Level 9

Re: Help with integers

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", "Smiley Sad\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)
0 Kudos
Highlighted
Level 7

Re: Help with integers

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.
0 Kudos
Highlighted
Level 10

Re: Help with integers

"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", "Smiley Sad\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"}
0 Kudos
Highlighted
Level 9

Re: Help with integers

"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:
Smiley Sad\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)
0 Kudos
Highlighted
Level 10

Re: Help with integers

"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 Smiley Tongue
0 Kudos
Highlighted
Level 16

Re: Help with integers

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
0 Kudos
Highlighted
Level 9

Re: Help with integers

"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)
0 Kudos
Highlighted
Level 16

Re: Help with integers

"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
0 Kudos
Highlighted

Re: Help with integers

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