40 billion in variable

I'm trying to do a bitcoin calculator, however I can't get the difficulty (40007470271) to any variable

1
2
3
4
5
6
7
					uint64_t diff = GetDlgItemInt(hWnd, IDC_DIFF, NULL, TRUE);
					uint64_t speed = GetDlgItemInt(hWnd, IDC_SPEED, NULL, TRUE);
					uint64_t price = GetDlgItemInt(hWnd, IDC_PRICE, NULL, TRUE);

					stringstream ss;
					ss << diff << " - " << speed << " - " << price;
					MessageBox(hWnd, ss.str().c_str(), NULL, NULL);


diff returns 0, even when I just do GetDlgItemInt to the stringstream it's 0, how should I somehow save the variable so I can use it in calculation?

I also tried getting value as a text and then converting it to 64bit int, but I'm getting some weird number, over 300 Billion...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
					int len = SendMessage(GetDlgItem(hWnd, IDC_DIFF), WM_GETTEXTLENGTH, 0, 0);

					string str;
					GetDlgItemText(hWnd, IDC_DIFF, (char*)&str, len+1);

					uint64_t i;

					stringstream ss;
					ss << str;
					ss >> i;

					ss.str(string());
					ss.clear();
					ss << i;

					MessageBox(hWnd, ss.str().c_str(), NULL, NULL);
Last edited on
Line 4 could be the problem. You are casting the refference of a string object to a cstring, what you probably want is something like GetDlgItemText(hWnd, IDC_DIFF, (char*)&str[0], len+1);
Why not str.c_str()?
@naraku9333

still same, gives me 343597383680 (343 597 383 680)
also looks like it doesn't matter what I put in box, it is always the same number

@Lachlan

I need it as integer so I can do calculations with it

--------------------------------------------------------------

edit: I just noticed that stringstream and string I made for testing are both returning -1 for their size..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
					int len = SendMessage(GetDlgItem(hWnd, IDC_DIFF), WM_GETTEXTLENGTH, 0, 0);

					string str;
					GetDlgItemText(hWnd, IDC_DIFF, (char*)&str[0], len+1);

					stringstream ss;
					ss << str;

					string teststr;
					ss >> teststr;

					char tmp[32];
					ss.seekg(0, ss.end);
					wsprintf(tmp, "%d - %d", ss.tellg(), teststr.size());
					MessageBox(hWnd, tmp, NULL, NULL);


same when I use GetDlgItemText(hWnd, IDC_DIFF, (char*)&str, len+1);

and yes, str returns correct value
Last edited on
Without knowing what GetDlgItemText and MessageBox do it's hard (impossible) to know what might be happening. But here's my best guess.
GetDlgItemText looks like it should take a c-string buffer to fill as its third argument. You're passing it a pointer to str's internal representation as a c-string. You're not meant to fill std::strings that way (if that's what's going on).
Try changing string str; to char buf[128];. Just pass buf to GetDlgItemText without all that subscripting/addressing/casting nonsense.
str fills fine, it's teststr that returns -1, and that's because stringstream gets broken somehow

also I noticed that no matter what I can't store more than 2^32-1 to the uint64_t, even when I compile for 64bit (the 64bit support isn't default for express so I followed this guide on msdn: http://msdn.microsoft.com/en-us/library/9yb4317s.aspx)

1
2
3
4
					uint64_t i = 2147483649;
					char tmp[128];
					wsprintf(tmp, "%d", i);
					MessageBox(hWnd, tmp, NULL, NULL);


returns -2147483647

therefore I assume it actually is compiling for 64bit, but is not 64bit, right?
1
2
string str;
GetDlgItemText(hWnd, IDC_DIFF, (char*)&str[0], len+1);

Undefined behavior. str is empty and does not have [0] element at all.
If you would initialize to have enoug characters to store written data it will work fine, but is still mess up string internals big time. Example:
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <string>
#include <cstring>


int main()
{
	std::string str(20, 'a');
	std::strcpy(&str[0], "bbbbbbb");
	std::cout << str;
}

wsprintf(tmp, "%d", i);
%d denotes type int. i is not int in your code. You need %lld here.
Last edited on
str fills fine
See:
http://msdn.microsoft.com/en-us/library/aa922589.aspx

It expects a buffer not a string. It should crash.


returns -2147483647 The problem is %d which expects an int.
thanks all,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
					int len = SendMessage(GetDlgItem(hWnd, IDC_DIFF), WM_GETTEXTLENGTH, 0, 0);

					char *tmp = new char[len+1];
					GetDlgItemText(hWnd, IDC_DIFF, tmp, len+1);

					stringstream ss;
					ss << tmp;

					uint64_t i;
					ss >> i;

					tmp[0] = '\0';

					wsprintf(tmp, "%I64d", i);
					MessageBox(hWnd, tmp, NULL, NULL);
					delete[] tmp;


works fine, I just dont quite understand, as
GetDlgItemText(hWnd, IDC_DIFF, (char*)&str, len+1);

worked correctly all the time before

edit: is there function similar to GetDlgItemText that uses strings instead of char arrays?
edit2: is there 64bit double/float ?
Last edited on
1
2
3
I just dont quite understand, as
/*...*/
worked correctly all the time before
It just seems to work. YOu write to some random memory. Which can be overwritten again by owner or cause problems for said owner. It is like scratching messages on random car in parking lot: it works. Maybe.

edit: is there function similar to GetDlgItemText that uses strings instead of char arrays?
All WinAPI (and external API in general) uses most simple types.

is there 64bit double/float ?
IEEE doubles are 64 bit long. floats are 32 bit long.

1
2
3
4
stringstream ss;
ss << tmp;
//Is better written as
std::istringstream ss(tmp);


Also wsprintf is Microsoft extension and is unportable (And unsupported. Even MSDN writes: "Note Do not use." ). Use sprintf or, better, snprintf. Or even better, store information in strings and use std::to_string

"%I64d" is another extension. (and it expects signed numbers AFAIK). USe %llu instead. All supported format specifiers can be found here: http://en.cppreference.com/w/cpp/io/c/fprintf
Last edited on
1. sooo just double i;?

2. sadly, with "%llu" i'm getting "lu", looks like it's not supported by wsprintf, sprintf is obsolete, so I can't compile and I somehow can't get snprintf from any header, tried stdio.h and cstdio ... http://www.cplusplus.com/reference/cstdio/snprintf/

edit: it looks like "%I64d" works with unsigned... http://i.imgur.com/PIFNsfs.jpg
Last edited on
1. sooo just double i;?
What do you actually mean by 64-bit double? An floating point variable which takes 64 bit in memory? Then yes. A floating point variable which can exactly represent any 64bit unsigned integer? Then no. Floating points stores only several significant digits precisely. 40007470271 should fit into double exactly thought.


sprintf is obsolete
Who said that? If something is obsolete it is wsprintf, as stated by Microsoft itself.
I somehow can't get snprintf from any header
Looks like your compiler is not supporting latest standard fully. I suggest updating it. (It looks that snprintf will be supported only in VS2014. Well, it took them longer than to release Duke Nukem Forever)

You can keep those function if you have no intention to let other users to compile your code, But in this case change uint64_t i; to std::int_64_t: %I64d expects signed integer.
Who said that? If something is obsolete it is wsprintf, as stated by Microsoft itself.

VS said that and that and won't let me compile... *unsafe, sorry
error C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead
Turn off this MS crap: http://stackoverflow.com/a/20753468

_s functions are not really safer and in some cases can lead to more problems because of false sence of security. Not to mention nonexisting portability.
You can get 64 bits of precision with an 80bit float. Try printing sizeof(long double) to see if your system/compiler supports 80bit floats, if the size is 10 (10 bytes, 8 bits per byte) then you can use long double to exactly store any 64 bit (signed or unsigned) integer. 1 bit sign, 15 bit exponent, 64 bit significand.
@MiiNiPaa
thanks!

@Lachlan
no, I'm getting 8
Topic archived. No new replies allowed.