agmark
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-26-2014
01:54 PM
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):
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.
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.
9 REPLIES 9
TheEndless
Channel Surfer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-26-2014
02:44 PM
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:
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)
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
agmark
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-26-2014
04:49 PM
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.
Many thanks.
EnTerr
Roku Guru
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-26-2014
05:09 PM
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"}
TheEndless
Channel Surfer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-26-2014
06:49 PM
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)
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
EnTerr
Roku Guru
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-27-2014
02:14 PM
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 😛
renojim
Community Streaming Expert
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-27-2014
08:37 PM
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:
-JT
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.
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.
TheEndless
Channel Surfer
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-27-2014
08:57 PM
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)
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
renojim
Community Streaming Expert
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-28-2014
02:15 AM
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.
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.
lukechinworth
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-17-2018
02:44 PM
Re: Help with integers
I ended up doing
left(msTimeStamp, 10).toInt()