Roku Developer Program

Join our online forum to talk to Roku developers and fellow channel creators. Ask questions, share tips with the community, and find helpful resources.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
agmark
Visitor

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 9
TheEndless
Channel Surfer

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", ":(\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
agmark
Visitor

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
EnTerr
Roku Guru

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", ":(\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
TheEndless
Channel Surfer

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:
:(\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
EnTerr
Roku Guru

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 😛
0 Kudos
renojim
Community Streaming Expert

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
Roku Community Streaming Expert

Help others find this answer and click "Accept as Solution."
If you appreciate my answer, maybe give me a Kudo.

I am not a Roku employee.
0 Kudos
TheEndless
Channel Surfer

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
renojim
Community Streaming Expert

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
Roku Community Streaming Expert

Help others find this answer and click "Accept as Solution."
If you appreciate my answer, maybe give me a Kudo.

I am not a Roku employee.
0 Kudos

Re: Help with integers

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