Go Down

Topic: Converting a String to int - "189148246403325952" --> int (Read 1 time) previous topic - next topic

insultcomicdog

I'm new to Arduino and Processing and am having a hard time doing what appears to be trivial.

I'm trying to convert a string like this "189148246403325952" to an int.

Here are a couple things I've tried which don't work or work partially :

since_id = int(since_id_str); //doesn't work
since_id = stringToNumber(since_id_str); //this doesn't work...189148246403325952 outputs as 8192
since_id = getInt(since_id_str); //this kind of works but doesn't convert full int...189148246403325952 outputs as 1891

some snippets I've found that should do the conversion:

Code: [Select]
int stringToNumber(String thisString) {
  int i, value = 0, length;
  length = thisString.length();
  for(i=0; i<length; i++) {
    value = (10*value) + thisString.charAt(i)-(int) '0';
  }
  return value;
}



Code: [Select]
int getInt(String text)
{
  char temp[6];
  text.toCharArray(temp, 5);
  int x = atoi(temp);
  return x;
}


One caveat of this conversion is that the length of since_id_str may be dynamic, and the length can't be hard coded.

Any ideas how to tackle this?



Graynomad

But that huge number doesn't fit into an int, so it can't be converted to one.

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

James C4S

189,148,246,403,325,952 is a slightly larger than the maximum 65,535 which an int can hold.  Long is too small as well.  You would need to store this value as a float.
Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

Nick Gammon

Actually, 32767 is the largest number you can put into a signed int.

I ported the "big number" library to the Arduino:

http://www.gammon.com.au/forum/?id=11519

Using that you can store:

Code: [Select]
52! = 80658175170943878571660636856403766975289505440883277824000000000000

But you have to work in the "big number" type.

But maybe you want the float type. That holds large numbers, just not with full precision.

Perhaps if you described what you are trying to do?

bibre

Quote
I ported the "big number" library to the Arduino:


Neat, Nick! 8)
Billy     http://www.z-world.com/operations/gbremer/

When you've eliminated the impossible,
whatever remains, however improbable, must be

insultcomicdog

Thanks for all the feedback...I should have realized that int had size limitations.

How would I go about converting the giant string to a float?

I tried this:

float since_id = atof(since_id_str);

but

189371928857935872  traces as 0.00

These large number strings are IDS of tweets that I'm parsing from XML:

https://dev.twitter.com/docs/api/1/get/search

I'm using this since_id data to scrape for tweets that have been created since my last GET query. I could probably store this data as a String/Char, but I figure I should learn how to do this conversion.

Any ideas?

AWOL

A float isn't going to be any better - still only 32 bits.
Save the ID as a string, or a set of BCD digits will save 50% of storage.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Nick Gammon


I'm using this since_id data to scrape for tweets that have been created since my last GET query. I could probably store this data as a String/Char, but I figure I should learn how to do this conversion.


Don't bother. You aren't going to be adding 5 to it are you? It's a string, as AWOL said. Store it as one.

Morris Dovey

You were on the right track, but needed to use an unsigned long long to hold the 8-byte result. A little tinkering produced
Code: [Select]
#include <stdio.h>
int main(void)
{  unsigned long long x = 0;
   char *c = "189148246403325952", *p = c;
   unsigned char b[32];
   int i;
   while (*p) x = 10 * x + *p++ - '0';
   printf("x = %llu = %llX\n",x,x);
   i = 0;
   do b[i++] = x & 255; while (x >>= 8);
   do printf("%2.2X ",b[--i]); while (i);
   puts("");
   return 0;
}
~/prj/fus/src/Samples: gcc ulltest.c -o ull
~/prj/fus/src/Samples: ull
x = 189148246403325952 = 29FFD53F4C22000
02 9F FD 53 F4 C2 20 00
There's always a better way!

insultcomicdog

I'm storing my IDs as a string/char now:

class variables are define like so:
Code: [Select]
char current_since_id_str[200] = "0"; <---this is my default value that I use for my initial GET request
char next_since_id_str[200];


After I make my GET call I store the response value here (189371928857935872):
Code: [Select]
if((finder.getString("<since_id>","</since_id>",next_since_id_str,200)!=0));


Now this is where I'm getting stuck...I want to set my current id to my next id.

I tried this:
current_since_id_str = next_since_id_str;

But I get an invalid array assignment error.

Clearly I'm a a noob at String manipulation. What am I doing wrong?

Graynomad

#10
Apr 16, 2012, 05:49 pm Last Edit: Apr 16, 2012, 05:51 pm by Graynomad Reason: 1
Quote
Clearly I'm a a noob at String manipulation.

You are not working with Strings here but arrays of characters that are often referred to as strings (if the array is NULL terminated.)

So a straight assignment will not work, have a look at the strcpy() function if you have NULL termination which I assume you do because you call something called getString(), or memcpy() if not.

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

insultcomicdog


I got it working...

Instead of this:
current_since_id_str = next_since_id_str;

I loop through the arrays like this:
for (int i=0; i <= 200; i++){
        current_since_id_str = next_since_id_str;
}

I'm finally getting the difference between chars and strings....Is the above solution good performance wise?

PaulS

Quote
Is the above solution good performance wise?

No. You have 2 200 byte arrays to hold strings like "189148246403325952". They hardly need to be anywhere near that large.

Graynomad

#13
Apr 17, 2012, 01:23 am Last Edit: Apr 17, 2012, 02:21 pm by Graynomad Reason: 1
Code: [Select]
for (int i=0; i <= 200; i++){
        current_since_id_str = next_since_id_str;
}


AKA memcpy(), except memcpy() will work, I don't see how that code will. Try

Code: [Select]
for (int i=0; i <= 200; i++){
        current_since_id_str[i] = next_since_id_str[i];
}


Quote
Is the above solution good performance wise?

Ok but can be a bit better

Code: [Select]
char * p_to =  current_since_id_str;
char * p_from =  next_since_id_str;
for (int i=0; i <= 200; p_from++, p_to++){
        *p_from = *p_to;
}


Although the compiler may optimise to something like this anyway.

EDIT: Oops, as AWOL pointed out, should be < 200 not <=

Even better just keep two pointers to the arrays and swap the pointers, that way you don't move any bytes around at all.

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

AWOL

Quote
Code:

for (int i=0; i <= 200; i++){
        current_since_id_str = next_since_id_str;
}


AKA memcpy(), except memcpy() will work, I don't see how that code will. Try


You'll notice the post ends in italics. This is what it looks like if you post it correctly, using [font=Verdana][[/font]code] [font=Verdana][[/font]/code] tags
Code: [Select]
for (int i=0; i <= 200; i++){
        current_since_id_str[i] = next_since_id_str[i];
}


Though that code will, of course, read and write beyond the end of 200 element arrays.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Go Up