C++ : storing a 13 digit number always fails

旧时模样 提交于 2021-01-29 15:30:36

问题


I'm programming in C++ and I have to store big numbers in one of my exercices. The biggest number i have to store is : 9 780 321 563 842.

Each time i try to print the number (contained in a variable) it gives me a wrong result (not that number).

A 32bit type isn't enough since 2^32 is a 10 digit number and I have to store a 13 digit number. But with 64 bits you can respresent a number that has 20digits. So I tried using the type "uint64_t" but that didn't work for me and I really don't understand why.

So I searched on the internet to find which type would be sufficient for my variable to fit in. I saw on this forum persons with the same problem but they solved it using long long int or long double as type. But none worked for me (neither did long float).

I really don't know which other type could store that number, as I tried a lot but nothing worked for me.

Thanks for your help! :)

-- EDIT : The code is a bit long and complex and would not matter for the question, so this is actually what I do with the variable containing that number :

string barcode_s = "9780321563842";
uint64_t barcode = atoi(barcode_s.c_str()); 
cout << "Barcode is : " << barcode << endl;

Off course I don't put that number in a variable (of type string) "barcode_s" to convert it directly to a number, but that's what happen in my program. I read text from an input file and put it in "barcode_s" (the text I read and put in that variable is always a number) and then I convert that string to a number (using atoi).

So i presume the problem comes from the "atoi" function?

Thanks for your help!


回答1:


The problem is indeed atoi: it returns an int, which is on most platforms a 32-bits integer. Converting to uint64_t from int will not magically restore the information that has been lost.

There are several solutions, though. In C++03, you could use stringstream to handle the conversion:

std::istringstream stream(barcode_s);
unsigned long barcode = 0;
if (not (stream >> barcode)) { std::abort(); }

In C++11, you can simply use stoul or stoull:

unsigned long long const barcode = std::stoull(barcode_s);



回答2:


Your number 9 780 321 563 842 is hex 8E52897B4C2, which fits into 44 bits (4 bits per hex digit), so any 64 bit integer, no matter if signed or unsigned, will have space to spare. 'uint64_t' will work, and it will even fit into a 'double' with no loss of precision.

It follows that the remaining issue is a mistake in your code, usually that is either an accidental conversion of the 64 bit number to another type somewhere, or you are calling the wrong fouction to print a 64 bit integer.

Edit: just saw your code. 'atoi' returns int. As in 'int32_t'. Converting that to 'unit64_t' will not reconstruct the 64 bit number. Have a look at this: http://msdn.microsoft.com/en-us/library/czcad93k.aspx




回答3:


The atoll () function converts char* to a long long.

If you don't have the longer function available, write your own in the mean time.

   uint64_t result = 0 ;
   for (unsigned int ii = 0 ; str.c_str()[ii] != 0 ; ++ ii)
   {
      result *= 10 ;
      result += str.c_str () [ii] - '0' ;
   }


来源:https://stackoverflow.com/questions/26326434/c-storing-a-13-digit-number-always-fails

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!