I'm writing a C++ code that converts an unsigned base 10 integer to any other base between 2 and 36. I haven't coded in a while so I'm kind of re-learning everything. My questions are: how can I keep it to just printf, without the cout at the end, and still display the ascii value. And is it possible to make it simple(basic).Sorry if I didn't format properly.
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string>
using namespace std;
int main()
{
int InitialNum, BaseNum, Num, x;
string FinalNum, Temp;
printf("Enter an unsigned integer of base ten: \n");//Prompt user for input
scanf_s("%d", &InitialNum);
printf("Enter the base you want to convert to (min2, max36): \n");
scanf_s("%d", &BaseNum);
x = InitialNum; //save the base 10 number to display at the end
while (InitialNum != 0) //continue dividing until original input is 0
{
Num = InitialNum % BaseNum; //save remainder to Num
int ascii = 48; //declare conversion variable (from int to char)
for (int i = 0; i < 32; ++i)//for loop converts Num from int 0-15 to char '0'-'9', 'A'-'F'
{
if(Num == i)
Temp = ascii;
ascii += 1;
if (ascii == 58)//skip from 9 to A on the ascii table and continue
ascii = 65;
}
FinalNum = Temp + FinalNum;//add to the final answer(additions to the left)
InitialNum /= BaseNum; //the initial base10 number gets divided by the base and saved as the quotient
}
printf("The number %d converted to base %d is:", x, BaseNum);
cout<<(FinalNum);
system("PAUSE");
return 0;
}
In order to output a std::string with printf you have to serve it to printf as a null-terminated string, the C style string. Or, well, you don't absolutely have to: you could print one character at a time. But it's most easy and practical to serve it as a null-terminated string.
You can do that via the .c_str() member function, hence:
printf( "%s\n", FinalString.c_str() );
Note that using std::string can be expensive at this low level of things, due to the dynamic allocation(s). E.g., (http://www.strudel.org.uk/itoa/), timing various implementations of itoa, found a 40x penalty.
Related
I am dealing with a programming question where I need to divide a very big number, of the order of 10^50000 by another of the order of 1000, in order to figure out if one is divisible by the other. So I need to use strings to store this large number.
I don't know any method to divide a string by a number. Can anyone point me to an algorithm?
Here is a start of an algorithm. It seems to do what you are asking for: it performs "long division" in 4 character chunks, and keeps track of the remainder. It prints the remainder at the end. You should be able to adapt this to your specific needs. Note - doing this in 4 bytes chunks makes it significantly faster than conventional one-character-at-a-time algorithms, but it does rely on b being small enough to fit in an int (hence the 4 character chunks).
#include <stdio.h>
#include <string.h>
int main(void) {
char as[]="123123123123126";
int l = strlen(as);
int rem;
int lm = l % 4; // the size of the initial chunk (after which we work in multiples of 4)
char *ap=as; // a pointer to keep track of "where we are in the string"
int b=123; // the divisor
int a;
sscanf(ap, "%4d", &a);
while(lm++ < 4) a /= 10;
// printf("initial a is %d\n", a);
rem = a % b;
for(ap = as + (l%4); ap < as + l; ap += 4) {
// printf("remainder = %d\n", rem);
sscanf(ap, "%4d", &a);
// printf("a is now %d\n", a);
rem = (a + 10000*rem) %b;
}
printf("remainder is %d\n", rem);
return 0;
}
Output:
remainder is 3
This needs some cleaning up but I hope you get the idea.
char *toBin(unsigned long long num)
{
char s[9999];
const int size= 9999;
char *temp = new char[size];
int i, j;
int binBase = 2;
for(i=0; num!= 0; i++)
{
s[i] = num % binBase + '0';
num /= binBase;
}//get backwards binary
for(j=0; i>=0; j++)
{
i--;
temp[j]=s[i];
}//reverse binary sequence
//increments one more so need to decrement
temp[--j] = '\0';
return temp;
delete temp;
}
If I had "82" in a char array, I first converted the "82" to the decimal 82 and gave 82 to the function above to convert to binary. This only works within a certain limit of digits.
I think my problem is that unsigned long long can only hold a certain amount of digits so when it exceeds that limit, some random stuff sent to the function, which prints out the wrong binary.
The above function converts a unsigned long long num to binary. I realized that a better approach would be to look at each character in the char array, rather than converting it to a number first, and and use those values to convert to binary. However, I'm having a hard time trying to put it to code. Any suggestions or help would be appreciated.
the GNU Multiple Precision (GMP) library has the functionality to print any size number in any base. The following is an example.
#include <iostream>
#include <gmpxx>
int main()
{
std::string numstr = "1234123412341234123412341234";
// initialize mpz_class to have numstr in it (given in base 10)
mpz_class bigint(numstr, 10);
// convert to binary (base 2)
std::string binstr = bigint.get_str(2);
std::cout << numstr << " -> " << binstr << std::endl;
return 0;
}
output of program
1234123412341234123412341234 -> 111111110011010111110011000011110100100000101001110100011000000101000011000000000111110010
Allocating an array of 9999 char on the stack is ill-advised because it might be too big for your platform. Anyway, you can easily calculate the maximum number of digits (+terminator) needed: CHAR_BIT*sizeof num+1.
Also, there is no need to allocate an equal amount on the heap.
Do not be afraid of pointers:
Init a pointer to the last byte
Set that to zero
Add all digits beginning with the smallest (at least one, even if the number is 0).
Return a copy of the finished number.
I'm trying to find a way to find the length of an integer (number of digits) and then place it in an integer array. The assignment also calls for doing this without the use of classes from the STL, although the program spec does say we can use "common C libraries" (gonna ask my professor if I can use cmath, because I'm assuming log10(num) + 1 is the easiest way, but I was wondering if there was another way).
Ah, and this doesn't have to handle negative numbers. Solely non-negative numbers.
I'm attempting to create a variant "MyInt" class that can handle a wider range of values using a dynamic array. Any tips would be appreciated! Thanks!
Not necessarily the most efficient, but one of the shortest and most readable using C++:
std::to_string(num).length()
The number of digits of an integer n in any base is trivially obtained by dividing until you're done:
unsigned int number_of_digits = 0;
do {
++number_of_digits;
n /= base;
} while (n);
There is a much better way to do it
#include<cmath>
...
int size = trunc(log10(num)) + 1
....
works for int and decimal
If you can use C libraries then one method would be to use sprintf, e.g.
#include <cstdio>
char s[32];
int len = sprintf(s, "%d", i);
"I mean the number of digits in an integer, i.e. "123" has a length of 3"
int i = 123;
// the "length" of 0 is 1:
int len = 1;
// and for numbers greater than 0:
if (i > 0) {
// we count how many times it can be divided by 10:
// (how many times we can cut off the last digit until we end up with 0)
for (len = 0; i > 0; len++) {
i = i / 10;
}
}
// and that's our "length":
std::cout << len;
outputs 3
Closed formula for the longest int (I used int here, but works for any signed integral type):
1 + (int) ceil((8*sizeof(int)-1) * log10(2))
Explanation:
sizeof(int) // number bytes in int
8*sizeof(int) // number of binary digits (bits)
8*sizeof(int)-1 // discount one bit for the negatives
(8*sizeof(int)-1) * log10(2) // convert to decimal, because:
// 1 bit == log10(2) decimal digits
(int) ceil((8*sizeof(int)-1) * log10(2)) // round up to whole digits
1 + (int) ceil((8*sizeof(int)-1) * log10(2)) // make room for the minus sign
For an int type of 4 bytes, the result is 11. An example of 4 bytes int with 11 decimal digits is: "-2147483648".
If you want the number of decimal digits of some int value, you can use the following function:
unsigned base10_size(int value)
{
if(value == 0) {
return 1u;
}
unsigned ret;
double dval;
if(value > 0) {
ret = 0;
dval = value;
} else {
// Make room for the minus sign, and proceed as if positive.
ret = 1;
dval = -double(value);
}
ret += ceil(log10(dval+1.0));
return ret;
}
I tested this function for the whole range of int in g++ 9.3.0 for x86-64.
int intLength(int i) {
int l=0;
for(;i;i/=10) l++;
return l==0 ? 1 : l;
}
Here's a tiny efficient one
Being a computer nerd and not a maths nerd I'd do:
char buffer[64];
int len = sprintf(buffer, "%d", theNum);
Would this be an efficient approach? Converting to a string and finding the length property?
int num = 123
string strNum = to_string(num); // 123 becomes "123"
int length = strNum.length(); // length = 3
char array[3]; // or whatever you want to do with the length
How about (works also for 0 and negatives):
int digits( int x ) {
return ( (bool) x * (int) log10( abs( x ) ) + 1 );
}
Best way is to find using log, it works always
int len = ceil(log10(num))+1;
Code for finding Length of int and decimal number:
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int len,num;
cin >> num;
len = log10(num) + 1;
cout << len << endl;
return 0;
}
//sample input output
/*45566
5
Process returned 0 (0x0) execution time : 3.292 s
Press any key to continue.
*/
There are no inbuilt functions in C/C++ nor in STL for finding length of integer but there are few ways by which it can found
Here is a sample C++ code to find the length of an integer, it can be written in a function for reuse.
#include<iostream>
using namespace std;
int main()
{
long long int n;
cin>>n;
unsigned long int integer_length = 0;
while(n>0)
{
integer_length++;
n = n/10;
}
cout<<integer_length<<endl;
return 0;
}
Here is another way, convert the integer to string and find the length, it accomplishes same with a single line:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
long long int n;
cin>>n;
unsigned long int integer_length = 0;
// convert to string
integer_length = to_string(n).length();
cout<<integer_length<<endl;
return 0;
}
Note: Do include the cstring header file
The easiest way to use without any libraries in c++ is
#include <iostream>
using namespace std;
int main()
{
int num, length = 0;
cin >> num;
while(num){
num /= 10;
length++;
}
cout << length;
}
You can also use this function:
int countlength(int number)
{
static int count = 0;
if (number > 0)
{
count++;
number /= 10;
countlength(number);
}
return count;
}
#include <math.h>
int intLen(int num)
{
if (num == 0 || num == 1)
return 1;
else if(num < 0)
return ceil(log10(num * -1))+1;
else
return ceil(log10(num));
}
Most efficient code to find length of a number.. counts zeros as well, note "n" is the number to be given.
#include <iostream>
using namespace std;
int main()
{
int n,len= 0;
cin>>n;
while(n!=0)
{
len++;
n=n/10;
}
cout<<len<<endl;
return 0;
}
As a part of a larger program, I must convert a string of numbers to an integer(eventually a float). Unfortunately I am not allowed to use casting, or atoi.
I thought a simple operation along the lines of this:
void power10combiner(string deciValue){
int result;
int MaxIndex=strlen(deciValue);
for(int i=0; MaxIndex>i;i++)
{
result+=(deciValue[i] * 10**(MaxIndex-i));
}
}
would work. How do I convert a char to a int? I suppose I could use ASCII conversions, but I wouldn't be able to add chars to ints anyways(assuming that the conversion method is to have an enormous if statement that returns the different numerical value behind each ASCII number).
There are plenty of ways to do this, and there are some optimization and corrections that can be done to your function.
1) You are not returning any value from your function, so the return type is now int.
2) You can optimize this function by passing a const reference.
Now for the examples.
Using std::stringstream to do the conversion.
int power10combiner(const string& deciValue)
{
int result;
std::stringstream ss;
ss << deciValue.c_str();
ss >> result;
return result;
}
Without using std::stringstream to do the conversion.
int power10combiner(const string& deciValue)
{
int result = 0;
for (int pos = 0; deciValue[pos] != '\0'; pos++)
result = result*10 + (deciValue[pos] - '0');
return result;
}
EDITED by suggestion, and added a bit of explanation.
int base = 1;
int len = strlen(deciValue);
int result = 0;
for (int i = (len-1); i >= 0; i--) { // Loop right to left. Is this off by one? Too tired to check.
result += (int(deciValue[i] - '0') * base); // '0' means "where 0 is" in the character set. We are doing the conversion int() because it will try to multiply it as a character value otherwise; we must cast it to int.
base *= 10; // This raises the base...it's exponential but simple and uses no outside means
}
This assumes the string is only numbers. Please comment if you need more clarification.
You can parse a string iteratively into an integer by simply implementing the place-value system, for any number base. Assuming your string is null-terminated and the number unsigned:
unsigned int parse(const char * s, unsigned int base)
{
unsigned int result = 0;
for ( ; *s; ++s)
{
result *= base;
result += *s - '0'; // see note
}
return result;
}
As written, this only works for number bases up to 10 using the numerals 0, ..., 9, which are guaranteed to be arranged in order in your execution character set. If you need larger number bases or more liberal sets of symbols, you need to replace *s - '0' in the indicated line by a suitable lookup mechanism that determines the digit value of your input character.
I would use std::stringstream, but nobody posted yet a solution using strtol, so here is one. Note, it doesn't perform handle out-of-range errors. On unix/linux you can use errno variable to detect such errors(by comparing it to ERANGE).
BTW, there are strtod/strtof/strtold functions for floating-point numbers.
#include <iostream>
#include <cstdlib>
#include <string>
int power10combiner(const std::string& deciValue){
const char* str = deciValue.c_str();
char* end; // the pointer to the first incorrect character if there is such
// strtol/strtoll accept the desired base as their third argument
long int res = strtol(str, &end, 10);
if (deciValue.empty() || *end != '\0') {
// handle error somehow, for example by throwing an exception
}
return res;
}
int main()
{
std::string s = "100";
std::cout << power10combiner(s) << std::endl;
}
I have an int array that represents a very large number such as:
// ...
unsigned int n1[200];
// ...
n1 = {1,3,4,6,1,...} ==> means my number is 13461...
How can I convert that large number to its hex value?
So here is my take on the problem:
You have an array of digits.
You want to build an unsigned int from this array of digits.
The array of digits could be either HEX digits, or DECIMAL digits.
To build this unsigned long long, assuming an array of DECIMAL digits:
unsigned long long myNum = 0;
unsigned int n1[200];
for (int i=0; i < n1.length ; i++ ){
myNum += pow(10,i) * n1[n1.length - i];
}
To build this unsigned long long, assuming an array of HEX digits:
for (int i=0; i < n1.length ; i++ ){
myNum += pow(16,i)* n1[n1.length - i];
}
(Notice the base 16)
Disclaimer: limited to exactly 16 digits MAX stored in your array. After that you will overrun the buffer
If it is just a matter of DISLAYING the number in the correct format...
Well, an int is an int is an int... (in memory).
There are 10 fingers on my hands whether or not I call that number 10, or A.
If you want to format the number for DISPLAY in hex, then try something like:
unsigned int i = 10;
//OR
unsigned int i = 0xA;
printf("My number in hex: %x", i);
printf("My number in decimal: %d", i);
I'm unsure if you want the hexadecimal represented as a string. If that's
the case, here's some code:
#include <iostream>
#include <stack>
using namespace std;
string toHexa(int num){
string digit = "0123456789ABCDEF", numStr = "";
stack<char> s;
do {
s.push(digit[num%16]);
num /= 16;
} while (num != 0);
while (!s.empty()){
numStr += s.top();
s.pop();
}
return numStr;
}
int main(){
int num = 235; // EB in hexa
cout << num << " to hexadecimal: " << toHexa(num) << endl;
return 0;
}
You could use the GMP library to make this relatively straightforward.
Use basic_stringstream<unsigned int> to wrap your array.
Use operator << to read it into a mpz_t variable.
Create another basic_stringstream<unsigned int> for your result.
Use std::hex and operator >> to write the variable back out in hexadecimal.
That would work on ASCII digits, but yours aren't. You can still use GMP, but you'll want to use the mpn_get_str and mpn_set_str functions instead. You'll need to copy your digits into an unsigned char[] and then you can specify the base for conversion to mp_limb_t and back to a string of digits.