I'm wanting to print an int array with 8 bytes and convert it to bin & hex with the output as such:
0 00000000 00
1 00000001 07
...
I've finished creating the binary convert function. I want to use the same function as the binary conversion -with an array, but check the left half with the right half and solve each different sided of the 8 bytes; left most -3 and right most is -7.
What am I doing wrong? I cannot figure out how to implement it and I know my hex function is all out of wack.
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
const int num = 8; //may not be needed -added for hex
void Generatebinary(int arr[]);
void GeneratehexDec(int arr[]);
void print_binary(int arr[]); //haven't created yet
int main()
{
int arr[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
int i = 1;
while (i < 256)
{
Generatebinary(arr);
print_binary(arr); //not created yet
GeneratehexDec(arr);
i++;
}
}
void Generatebinary(int arr[])
{
for (int i = 7; i > 0; i--)
{
if (arr[i] == 1)
arr[i] = 0;
else if (arr[i] == 0)
{
arr[i] = 1;
break;
}
}
}
void GereatehexDec(int num)
{ //improper use
int a;
int i;
int answer[] = { };
a = num % 16;
i++;
answer[i] = num;
for (int i = num; i > 0; i--)
{
cout << answer[i];
}
cout << a;
}
First of all, you can't do int answer[] = { }; an array has to be pre-allocated (indicating how many elements it will store) or has to be dynamically allocated during run-time, then be freed, you have to manage your memory, not forget to deallocate... It's for this reason that Stroustrup tells you to not use arrays unless necessary. Use std::vector
void GereatehexDec(int num)
{ //improper use
int a = 0; // always initialize your variables
int i = 0; // is this i supposed to be the same as the i in the for loop below?
std::vector<int> answer;
a = num % 16;
i++; // this doesn't make sense
answer.at(i) = num;
for (int i = num; i > 0; i--) // what about the i variable you declared previously?
{
cout << answer.at(i);
}
cout << a;
}
Here's a template function that could help you (converts numbers into string hex)
template <typename I> std::string n2hexstr(I w, size_t hex_len = sizeof(I) << 1) {
static const char* digits = "0123456789ABCDEF";
std::string rc(hex_len, '0');
for (size_t i = 0, j = (hex_len - 1) * 4; i<hex_len; ++i, j -= 4)
rc[i] = digits[(w >> j) & 0x0f];
return "0x" + rc;
}
int main() {
std::cout << n2hexstr(127);
}
Related
So, what I basically need is to calculate value of an exponential function (2^n)*(2^(n-1)-1) using c++, where n is a unsigned int type user input. Since n can be assigned any value in unsigned int range, I cannot simply calculate function value and assign it to some unsigned int variable (because resulting number will clearly be out of said range). Therefore, it seems reasonable to me to somehow get my desired function value number by number and write each number as a array element. The only struggle is to realise this method.
Any ideas (both using proposed method or any other one) would be much appreciated.
edit:
Right now I have the following code:
outdated
As expected, it will only work with small values of n
Edit 2: as one of the commentators suggested, I've done some binary numbers by hand. It was pretty fruitful, but I still need sime assistance. Now i have the following code, which will correctly output binary value of said function:
outdated
The only thing left is to convert this value to decimal and hexadecimal. I am not experienced at working with string class, so advice would be appreciated.
Edit 3: Thanks everyone for help. I've completed my program and converted it co C (not willingly, because my professor told me to do so). For anyone interested, the current version of code looks like that:
#include <stdio.h>
#include <stdlib.h>
void binary(unsigned int);
void hex(unsigned int);
void decimal(unsigned int);
int *calculatepower(unsigned int, unsigned int);
void addition(int*, int*, int);
int main(int argc, char** argv){
if (argc != 2){
printf("wrong number of arguments \n");
return -2;
}
unsigned int n = atoi(argv[1]);
printf("exponent - %d \n", n);
binary(n);
hex(n);
decimal(n);
return 0;
}
void binary(unsigned int n){
int i;
printf("binary - ");
for (i=n-1; i>0; i--)
printf("1");
for (i=n; i>0; i--)
printf("0");
printf("\n");
}
void hex(unsigned int nn){
int ones = nn-1;
int zeroes = nn;
int hexzeroes=0, hexfs=0, i;
char switchf, switchzero;
while (zeroes > 3){
hexzeroes+=1;
zeroes-=4;
}
switch (zeroes){
case 0:
break;
case 1:
switchzero='E';
ones-=3;
break;
case 2:
switchzero='C';
ones-=2;
break;
case 3:
switchzero='8';
ones-=1;
break;
default:
break;
}
while (ones>3){
hexfs+=1;
ones-=4;
}
switch (ones){
case 0:
switchf='\0';
break;
case 1:
switchf='1';
break;
case 2:
switchf='3';
break;
case 3:
switchf='7';
break;
default:
break;
}
printf("hexadecimal - %c", switchf);
for (i=0; i<hexfs; i++)
printf("F");
if (zeroes !=0) printf("%c", switchzero);
for (i=0; i<hexzeroes; i++)
printf("0");
printf("\n");
}
void decimal(unsigned int nn){
unsigned int n=nn;
int *str,*powerstr, i, flag=0;
// decimal = 2^n+...+2^((2*n)-1)
unsigned int size = (2*n)/3 + 2;
str = (int*)calloc(size, sizeof(*str));
if(str==NULL)
{
printf("unable to allocate memory");
exit(0);
}
for (i=0; i<size; i++)
{
str[i] = 0;
}
for (n;n<2*nn-1;n++){
powerstr = calculatepower( n, size);
addition(str,powerstr,size);
}
printf("decimal - ");
for (i=0;i<size;i++) {
if ((*(str+i)==0) && (flag==0)){
continue;
}
printf("%d", *(str+i));
flag+=1;
}
}
int *calculatepower(unsigned int n, unsigned int size){
int i, j, buf=0, *powerstr;
powerstr = (int*)calloc(size, sizeof(*powerstr));
for (i=0; i<size; i++)
{
powerstr[i] = 0;
}
powerstr[size-1]=1;
for(j=0;j<n;j++) {
for (i=size-1; i > -1; i--) {
powerstr[i] = powerstr[i] * 2;
if (buf!=0) {
powerstr[i] += 1;
buf=0;
}
if (powerstr[i] > 9) {
buf = 1;
powerstr[i]%=10;
}
}
}
return powerstr;
}
void addition(int *str, int *powerstr, int size){
int i, buf=0;
for (i=size-1; i > -1; i--) {
str[i] = powerstr[i] + str[i];
if (buf!=0) {
str[i] += 1;
buf=0;
}
if (str[i] > 9) {
buf = 1;
str[i]%=10;
}
}
}
Unfortunately, I do not have enough time to polish it. The current biggest problem is not freeing allocated memory and I will fix it later, but I won't update queastion anymore. Thanks again everyone for your answers and comments.
For 16 bit ints it's doable and produces about 40k decimal chars. For 32 bit ints, not so much as it's about 10^20 decimal chars which is beyond anything possible. Even outputting a million chars per second would take longer than the lifetime of the universe.
Here's code for 16 bit ints. Runs in about 3 seconds for n = 65535 not including output time. It has performance improvements by accumulating base 10 sums and normalizing occasionally to prevent overflow.
#include <iostream>
#include <vector>
#include <string>
#include <cstdint>
using std::cout;
using std::vector;
using std::string;
struct BigDecPower2 {
static constexpr uint32_t Normalize_Max{ 26 }; // int8:3, int16:10, int32:26
vector<uint32_t> v;
uint32_t top;
uint32_t normalize_count;
BigDecPower2(uint32_t n) : v(n), top(0), normalize_count(0) {};
void normalize()
{
normalize_count = 0;
for (uint32_t i = 0;; i++)
{
v[i + 1] += v[i] / 10u;
v[i] = v[i] % 10u;
if (i >= top && v[i + 1] == 0)
{
top = i;
return;
}
}
}
void times2() {
for (uint32_t i = 0; i <= top; i++)
v[i] *= 2;
if ((++normalize_count) > Normalize_Max)
normalize();
}
};
void add(BigDecPower2& v1, const BigDecPower2& v2)
{
uint32_t max_top = v1.top > v2.top ? v1.top : v2.top;
for (uint32_t i = 0; i <= max_top; i++)
v1.v[i] += v2.v[i];
if (++v1.normalize_count < v2.normalize_count)
v1.normalize_count = v2.normalize_count;
if (v1.normalize_count > v1.Normalize_Max)
v1.normalize();
}
void print_base(unsigned int n, int number_base)
{
int64_t ones = n-1;
int64_t zeros = n;
if (number_base ==2)
{
while (ones-- > 0)
cout << '1';
while (zeros-- > 0)
cout << '0';
}
else if (number_base == 16) {
int resid = (ones + zeros) % 4;
if (resid == 0)
resid = 4;
cout << "~137F"[resid];
ones -= resid;
while ((ones -= 4) > 0)
cout << 'F';
cout << "8CEF"[ones + 3];
zeros /= 4;
while (zeros--)
cout << '0';
}
else if (number_base == 10)
{
BigDecPower2 v_accum(40000u);
BigDecPower2 v_pwr(40000u); v_pwr.v[0] = 1;
for (uint32_t i = 0; i < n - 1; i++)
{
add(v_accum, v_pwr);
v_pwr.times2();
}
for (uint32_t i = 0; i < n; i++)
v_accum.times2();
v_accum.normalize();
for (uint32_t i = v_accum.top; i != -1; i--)
cout << static_cast<char>(v_accum.v[i] + '0');
}
cout << '\n';
}
int main()
{
// calcs in about 3 seconds, outputs about 40k decimal chars
// print_base(0xffff, 10);
// Demo
for (int i = 1; i < 10; i++)
{
print_base(i, 2);
print_base(i, 16);
print_base(i, 10);
cout << '\n';
}
}
You can use unsigned long or unsigned long long (or uintX_t where X is the maximum supported size on your platform) if unsigned int cannot hold your output. If that's still not enough for your use case, then either implement your own big integer class, or use an existing library (recommended if you can afford it). There are a couple of them out there. For example, GNU Multiple Precision Arithmetic Library (GMP) and bigint-library. See this list for more.
In case you decided to go on your own and implement your own class, this might give you some clues on how to start. (Note that, for efficiency matters, number theory algorithms may be applied. It is not an easy task to come with a good implementation).
template<typename T = unsigned, int Base = 10> class Bigint {
std::vector<T> digits;
bool sign; // For e.g. true for + or 0, false for -
public:
Bigint() : digits(), sign(true) { }
Bigint(int x)
{
// Insert digits of x into digits vector
// Don't forget the sign
}
// Do the same with other types: short, long, unsigned, etc.
Bigint(const char *x)
{
// You need to parse x. Bad formatting is to be handled (tip: use exceptions)
}
// Provide an std::string version
Bigint(const Bigint& bi) : digits(bi.digits), sign(bi.sign) {}
Bigint& operator=(const Bigint& bi)
{
// Copy...
return *this;
}
// You also have to implement operators
Bigint& operator+(const Bigint& bi)
{
// Logic...
return *this;
}
// Other operators: -, /, %, bitwise, etc.
// Tip: you can use a helper class to be used by both / and % since they share a similar logic (for avoiding redundant code).
Bigint power(const Bigint& bi) // Provide other signatures: int, string, etc.
{
// Logic...
}
};
Using nested while loops to count the number of each character in a given string and put those numbers in an array. Then finding the largest number in the array to determine the most common character. Returning this character to the caller.
When placing a breakpoint |down (noted below) Im getting the first array value to be correct, and the second to be incorrect.
I don't know where I'm going wrong. I do have to admit I'm quite burned out right now, so it could be something easy I'm overlooking. I don't know.
#include <iostream>
using namespace std;
#include <string>
#include <string.h>
char median(char *);
int main() {
const int SIZE = 50;
char thing[SIZE];
char *strPtr;
cout << " give me a string: " << endl;
cin.getline(thing, SIZE);
strPtr = thing;
char mostcommon = median(strPtr);
cout << mostcommon;
}
char median(char *strPtr) {
char holder = 'x';
int numberof[50];
int counter = 0;
int arrayspacecounter = 0;
int thirdcounter;
int fourthcounter;
while (*strPtr != '\0') {
holder = *strPtr;
while (*strPtr != '\0') {
strPtr++;
if (holder == *strPtr) {
counter++;
}
}
numberof[arrayspacecounter] = counter; //counts the number of each character.
arrayspacecounter++;
strPtr++;
counter = 0;
}
v
// break point set HERE
^
//find the largest number in numberof[]
int largest = 0;
for (thirdcounter = 0; thirdcounter <= 100; thirdcounter++) {
for (fourthcounter = 1; fourthcounter <= 100; fourthcounter++) {
if (largest < numberof[fourthcounter]) {
largest = numberof[fourthcounter];
}
}
}
return *(strPtr + (largest));
}
numberof is not initialised so will initially contain junk values, any unused entries will still contain junk values where your breakpoint is. Use:
int numberof[50] = { 0 };
Next fourthcounter goes up to 100 but you only have 50 elements in numberof, replace the magic number 50 with a constant like MAX_ELEMENTS:
const size_t MAX_ELEMENTS = 50;
int numberof[MAX_ELEMENTS] = { 0 };
....
for (thirdcounter = 0; thirdcounter < MAX_ELEMENTS; thirdcounter++)
{
for (fourthcounter = 1; fourthcounter < MAX_ELEMENTS; fourthcounter++)
{
Alternatively just use the arrayspacecounter you have created already:
for (thirdcounter = 0; thirdcounter < arrayspacecounter; thirdcounter++)
{
for (fourthcounter = 1; fourthcounter < arrayspacecounter; fourthcounter++)
{
I'm not sure why you have two for loops at the end? The outer one seems redundant. Fixing various other bugs results in the working function:
char median(const char* strPtr)
{
const size_t MAX_ELEMENTS = 50;
int numberof[MAX_ELEMENTS] = { 0 };
int counter = 0;
int arrayspacecounter = 0;
int fourthcounter;
const char* temp = strPtr;
while (*temp != '\0')
{
const char* holder = temp;
while (*temp != '\0')
{
temp++;
if (*holder == *temp)
{
counter++;
}
}
numberof[arrayspacecounter] = counter; //counts the number of each character.
arrayspacecounter++;
temp = holder;
temp++;
counter = 0;
}
//find the largest number in numberof[]
int largest = 0;
for (fourthcounter = 1; fourthcounter < arrayspacecounter; fourthcounter++)
{
if (numberof[largest] < numberof[fourthcounter])
{
largest = fourthcounter;
}
}
return *(strPtr + (largest));
}
Your code could be much simpler though:
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
char median(const char*);
int main()
{
char mostcommon = median("test");
std::cout << mostcommon;
}
char median(const char* strPtr)
{
std::map<char, int> frequencies;
for (auto ch = strPtr; *ch != '\0'; ch++)
{
frequencies[*ch]++;
}
auto max = std::max_element(frequencies.begin(), frequencies.end(), [](const auto& a, const auto& b) { return a.second < b.second; });
return max->first;
}
Your program segfaults in median somewhere, my guess is that you're trying to use a position outside of the boundaries of your array somewhere.
If all you're wanting to count frequency try something simpler, like this for example.
#include <string>
#include<iostream>
int main()
{
std::string phrase;
std::cout << "Enter a phrase \n";
std::getline(std::cin,phrase);
int a = 'A'; //index 0 of your array
int count=0;int max=0;
int counter[26] = {0}; //array that will hold your frequencies
char highestFreq;
for(char c:phrase) {
if(!isspace(c)) count = ++counter[int(toupper(c))-a];
if(count>max) max=count, highestFreq=c;
}
std::cout << "max is: "<<max << ". The letter is '"<< highestFreq << "'.\n"<< std::endl;
}
In the following code, when I'm removing cout statement (line after //******)then it is causing a change in the value of "i".
I used TDM-GCC 4.9.2 32 bit release and TDM-GCC 5.1.0 compilers.
I ran this code on codechef and there it runs fine and cout statement is not affecting the value of "i".
#include<iostream>
using namespace std;
int subset(int [], int);
int main()
{
int size,i,ans;
cout<<"size of array : ";
cin>>size;
int arr[size];
for(i = 0 ; i<size;i++)
{
cin>>arr[i];
}
ans = subset(arr,size);
cout<<"ans = "<<ans;
return 0;
}
int subset(int arr[], int size)
{
int i,j, tsum=0, completed=0;
for(i = 0 ;i<size;i++)
tsum = tsum + arr[i];
int carr[tsum+1],temp;
for(i=0;i<size;i++)
{
temp = arr[i];
carr[temp] = 1;
for(j=i+1;j<size;j++)
{
temp = temp + arr[j];
carr[temp] = 1;
}
}
for(i=1;i<=tsum;i++)
{
if(carr[i]!=1)
{
//************************************
cout<<"i : "<<i<<endl;
break;
}
}
return i;
}
Sample input :
size of array : 3
1
2
5
sample output without cout statement :
ans = 6
sample output having cout statement :
i : 4
ans = 4
Actual answere is 4 for the input.
The main problem seems to be that carr is uninitialized.
It is declared as
int carr[tsum+1]
with no initializer.
Later on some elements are set, but always to 1:
carr[temp] = 1;
In the last loop carr is examined:
if(carr[i]!=1)
This condition makes no sense. Either carr[i] has been set, then it is guaranteed to be 1, or it is uninitialized, in which case this comparison has undefined behavior.
Note that variable-length arrays are not standard C++.
To solve the problems as stated by Some Programmer Dude and melpomene, i.e. Variable-length arrays are not standard C++ and carr is uninitialized. Use c++ vectors and initialize them correctly. That would look something like this:
#include <iostream>
#include <vector>
using namespace std;
int subset(const std::vector<int>, const int);
int main()
{
int size, i, ans;
cout << "size of array : ";
cin >> size;
std::vector<int> arr(size);
for (i = 0; i < size; i++)
{
cin >> arr[i];
}
ans = subset(arr, size);
cout << "ans = " << ans;
return 0;
}
int subset(const std::vector<int> arr, const int size)
{
int i, j, tsum = 0, completed = 0;
for (i = 0; i < size; i++)
tsum = tsum + arr[i];
std::vector<int> carr(tsum + 1, 0);
int temp;
for (i = 0; i < size; i++)
{
temp = arr[i];
carr[temp] = 1;
for (j = i + 1; j < size; j++)
{
temp = temp + arr[j];
carr[temp] = 1;
}
}
for (i = 1; i <= tsum; i++)
{
if (carr[i] != 1)
{
//************************************
cout << "i : " << i << endl;
break;
}
}
return i;
}
d[i] = char(c[i]);
This is not working for me in the below example.
I need my output to be converted to its character values, but after using char(int), its still giving output using the int datatype only.
#include <bits/stdc++.h>
using namespace std;
int main()
{
string str;
cin>>str;
int size=str.size();
int len=0;
if (size % 2 == 0)
{
len=size/2;
}
else
{
len=(size/2)+1;
}
int a[len],b[len],c[len],d[len],x,y;
int i=0,j=size-1;
while(i<len)
{
x=(int)str[i];
y=(int)str[j];
if (i == j)
{
a[i]=x;
}
else
{
a[i]=x+y;
}
b[i]=a[i]%26;
c[i]=x + b[i];
d[i]=char(c[i]);
cout<<"l : "<<d[i]<<endl;
i++;
j--;
}
return 0;
}
Your code fails because you are storing the values in an int[] array. d[i]=char(c[i]); is useless because all you are doing is converting an int to a char back to an int again. You are then outputting the array values as-is as int values instead of converting them back to actual char values.
Try something more like this instead:
#include <vector>
#include <string>
using namespace std;
int main()
{
string str;
cin >> str;
int size = str.size();
int len = (size / 2) + (size % 2);
// VLAs are a non-standard compiler extension are are not portable!
// Use new[] or std::vector for portable dynamic arrays...
//
// int a[len], b[len], c[len];
// char d[len];
//
std::vector<int> a(len), b(len), c(len);
std::vector<char> d(len);
int x, y, i = 0, j = (size-1);
while (i < len)
{
x = (int) str[i];
y = (int) str[j];
if (i == j)
{
a[i] = x;
}
else
{
a[i] = x + y;
}
b[i] = a[i] % 26;
c[i] = x + b[i];
d[i] = (char) c[i];
cout << "l : " << d[i] << endl;
++i;
--j;
}
return 0;
}
I'm writing a program for my OO class and I'm having some trouble with my cout statements. The program is supposed to take in a value and convert it to a bitwise array. My problem is that no matter what number I put in it couts every element in the array to 0. The assignment said to initialize every element to 0 in the constructor, but when comparing it to the & operator in the Query function it can only return false. Any suggestions? (Note: we can't use vectors or any of the premade functions.)
in header file:
private:
static const CSIZE = 8 * sizeof(char);
int arraySize;
unsigned char* barray;
in .cpp file
#include <iostream>
#include "bitarray.h"
using namespace std;
ostream& operator<< (ostream& os, const BitArray& a)
{
for (unsigned int i = 0; i < a.arraySize * a.CSIZE; i++)
os << a.Query(i);
return os;
}
BitArray::BitArray(unsigned int n)
{
if (n % CSIZE != 0)
arraySize = (n / CSIZE) + 1;
else
arraySize = n / CSIZE;
barray = new unsigned char[arraySize];
for (int i = 0; i < arraySize; i++)
barray[i] = 0;
}
unsigned char BitArray::Mask (unsigned int num) const
{
return (1 << num % CSIZE);
}
void BitArray::Set (unsigned int index)
{
unsigned int i = index / CSIZE;
barray[i] |= Mask (index);
}
bool BitArray::Query (unsigned int index) const
{
unsigned int i = index / CSIZE;
if (barray[i] & Mask (index))
return true;
return false;
}
Main program:
#include <iostream>
using namespace std;
#include "sieve.h"
#include "bitarray.h"
int main()
{
unsigned int i, max, counter = 0;
cout << "\nEnter a positive integer for the maximum value: ";
cin >> max;
BitArray ba(max);
Sieve(ba); // find the primes (marking the bits)
cout << "The bit array looks like this: \n"
<< ba
<< '\n';
cout << "\nPrimes less than " << max << ':' << '\n';
for (i = 0; i < max; i++)
{
if (ba.Query(i))
{
counter++;
cout << i;
if (counter % 8 == 0)
{
cout << '\n';
counter = 0;
}
else
cout << '\t';
}
}
cout << "\nGoodbye!\n";
return 0;
}