As you can read in the header it is about a rather simple topic. But I encountered something very odd while implementing possible different ways to get a quadratic sum of N numbers.
I implemented three different versions:
Quadratic Gauß sum (func: quadratGauss(int n) )
Iterative (func: quadratIterativeClassic(int n) )
Iterative via Bitoperation (func: quadratIterativeBitoperation(int n) )
All three functions have returned the same result as expected from the given Input. The Big question now is. How was it possible for the third function to work proper? The Code looks like this:
void quadratGauss(int n){
printf("+quadratGauss: \n");
int result = ((n*(n+1))*(2*n+1))/2;
printf("Result: %d\n----------------\n",result);
}
void quadratIterativClassic(int n){
int result;
printf("+quadratIterativClassic: \n");
for(int i;i<=n;i++)
result += i * i;
printf("Result: %d\n----------------\n",result);
}
void quadratIterativeBitOperation(int n){
int result;
printf("+quadratIterativeBitOperation: \n");
for(int i;i<=n;i++)
result += i^2;
printf("Result: %d\n----------------\n",result);
}
As you see I use the XOR operator. I originally wanted to use the shift-operator "<<" but i tried others as well. what where stunning when i tried the XOR operator: the result was still the same as before and the same as the other two functions. I thought this was not possible because the XOR is not an operator for the power-operation because C does not contain such an operator but still i got eventually the right result.
I tested the functions with different numbers of different "sizes". Nothing odd in the result of each function.
I've got no clue why. But there must be an explanation, doesn't it?
If you have one, I would appreciate alot the effort of writing down a possible reason, why you can implement this with the XOR operator.
here the whole main file:
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#define N 5000
void sumGauss(int n)
{
printf("+sumGauss: \n");
int result = (n*(n+1)/2);
printf("Result: %d\n----------------\n",result);
}
void sumClassic(int n)
{
printf("+sumClassic: \n");
int result = 0;
for(int i = 0; i <= n; i++)
result += i;
printf("Result: %d\n----------------\n",result);
}
void quadratGauss(int n){
printf("+quadratGauss: \n");
int result = ((n*(n+1))*(2*n+1))/2;
printf("Result: %d\n----------------\n",result);
}
void quadratIterativeBitOperation(int n){
int result;
printf("+quadratIterativeBitOperation: \n");
for(int i;i<=n;i++)
result += i^2;
printf("Result: %d\n----------------\n",result);
}
void quadratIterativClassic(int n){
int result;
printf("+quadratIterativClassic: \n");
for(int i;i<=n;i++)
result += i * i;
printf("Result: %d\n----------------\n",result);
}
void unevenSum(int n)
{
printf("+unevenSum: \n");
int uneven = 0;
int i=0;
for(i=1;i<= n;i+=2) {
uneven += i;
}
printf("Result: %d\n----------------\n",uneven*2);
}
void unevenSumModulo(int n)
{
printf("+unevenSumModulo: \n");
int result=0;
for(int i=0;i<=n;i++)
{
if( (i%1) == 0)
result += i;
}
printf("Result: %d\n----------------\n",result);
}
void unevenSumNico(int n)
{
printf("+unevenSumNico: \n");
int odd = 0;
int i=0;
for(i=1;i<= n;i++) {
odd += ((2*i)-1)/2;
}
printf("Result: %d\n----------------\n",odd);
}
void evenSum(int n)
{
printf("+evenSum: \n");
int result=0;
for(int i=0;i<=n;i++)
{
if( (i%2) == 0)
result += i;
}
printf("Result: %d\n----------------\n",result);
}
void Zins(float Kapital,int years)
{
printf("Zinstabelle fuer Grundkaptial %.2f Euro\n",Kapital);
printf("Kapitalstand zum Jahresende\n");
int i=0;
float K = Kapital;
for(int i =1;i<years+1;i++)
{
K = K *(1.f + 0.05f);
printf("Jahr: %2d Kapital: %.2f Euro\n",i,K);
}
}
int main(int argc, char** argv) {
sumGauss(N);
sumClassic(N);
quadratGauss(N);
quadratIterativeBitOperation(N);
quadratIterativClassic(N);
unevenSum(N);
unevenSumNico(N);
unevenSumModulo(N);
evenSum(N);
Zins(N);
return 0;
}
This would only be true for n = 0. Rest assured that you cannot implement squaring using just the XOR operator, even for integral types.
The behaviour of your code is currently undefined, as you don't initialise either i, or result. I suspect that your loop does not run at all and by the most amazing coincidence, result occupies the same memory in the subsequent functions as it does in the Guassian function. But don't ever rely on that behaviour. Other compilers might simply attempt to eat your cat.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char const *argv[]){
int i=0,n1;
scanf("%d",&n1);
void quadratGauss(int n){
printf("+quadratGauss: \n");
int result = ((n*(n+1))*(2*n+1))/6; // you made here mistake take 2 insted of 6.
printf("Result: %d\n----------------\n",result);
}
void quadratIterativClassic(int n){
int result=0;
printf("+quadratIterativClassic: \n");
for(i=1;i<=n;i++)
result += i * i;
printf("Result: %d\n----------------\n",result);
}
void quadratIterativeBitOperation(int n){
int result=0;
printf("+quadratIterativeBitOperation: \n");
for(i=1;i<=n;i++)
result += pow(i,2); //This is power fun to add series of quadrat
printf("Result: %d\n----------------\n",result);
}
//call the fun.
quadratGauss(n1);
quadratIterativClassic(n1);
quadratIterativeBitOperation(n1);
return 0;
}
:) Want to more about http://www.trans4mind.com/personal_development/mathematics/series/sumNaturalSquares.htm
https://en.wikipedia.org/wiki/Quadratic_Gauss_sum
First, its /6, not /2. See that quadratGauss is always 3 times the quadratIterativClassic. And I got completely different results for quadratIterativeBitOperation
n = 4
+quadratGauss:
Result: 90
----------------
+quadratIterativClassic:
Result: 30
----------------
+quadratIterativeBitOperation:
Result: 12
----------------
n = 5
+quadratGauss:
Result: 165
----------------
+quadratIterativClassic:
Result: 55
----------------
+quadratIterativeBitOperation:
Result: 19
----------------
n = 6
+quadratGauss:
Result: 273
----------------
+quadratIterativClassic:
Result: 91
----------------
+quadratIterativeBitOperation:
Result: 23
I think it your compiler must have ^ set as exponent instead of XOR
Related
I am a beginner starting in C and am doing some exercises on codewars. The exercise requires me to take a decimal int, convert it into binary and output the number of 1s in the binary number. Below my incomplete code. I store the binary in int b and I want to output it into an array so that I can run a loop to search for the 1s and output the sum.
Thanks in advance!
#include <stddef.h>
#include <stdio.h>
//size_t countBits(unsigned value);
int countBits(int d);
int main() {
int numD = 1234;
int numB = countBits(numD);
printf("The number %d converted to binary is %d \n", numD, numB);
}
int countBits(int d) {
if (d < 2) {
return d;
} else {
int b = countBits(d / 2) * 10 + d % 2; //convert decimal into binary
int c;
int bArray[c];
}
Your function is almost correct:
you should define the argument type as unsigned to avoid problems with negative numbers
you should just return b in the else branch. Trying to use base 10 as an intermediary representation is useless and would fail for numbers larger than 1023.
Here is a corrected version:
int countBits(unsigned d) {
if (d < 2) {
return d;
} else {
return countBits(d / 2) + d % 2;
}
}
There are many more efficient ways to compute the number of bits in a word.
Check Sean Eron Anderson's Bit Twiddling Hacks for classic and advanced solutions.
You can make an array char as one of the replies said, for example:
#include <stdio.h>
#include <string.h>
int main(){
int count=0;
int n,bit;
char binary[50];
printf("Enter a binary: \n");
scanf("%s",binary);
n=strlen(binary);
for(int i=0;i<n;i++){
bit=binary[i]-'0';
if (bit==1){
count=count+1;
}
}
printf("Number of 1's: %d\n",count);
return 0;
}
This should count the number of 1's of a given binary.
Try something like this!
edit: I know that binary[i]-'0' might be confusing, if you don't understand that..take a look at this:
There are definitely 'smarter'/more compact ways to do this, but here is one way that will allow you to count bits of a bit larger numbers
#include <stdio.h>
int count_bits(int x)
{
char c_bin[33];
int count=0;
int mask=1;
for( int i =0; i < 32; i++){
if (x & mask ){
count=i+1;
c_bin[31-i]='1';
}
else{
c_bin[31-i]='0';
}
mask=mask*2;
}
c_bin[32]='\0';
printf("%d has %d bits\n",x,count);
printf("Binary x:%s\n",c_bin);
return count;
}
int main()
{
int c=count_bits(4);
return 0;
}
Basically I have a function called MinSubTab that is supposed to calculate the sum of the array passed and also to change the value passed in the first argument from inside the function without using return. This is done with pointers. Anyway, I think it'd be easier if I just showed you the code so here it is:
maintab.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "tab.h"
int main(){
int *reftab;
int min;
reftab = (int *)malloc(sizeof(int) * NMAX);
InitTab(reftab,NMAX);
printf("\n Total: %d et min: %d", MinSumTab(&min, reftab, NMAX), min);
free(reftab);
return 0;
}
tab.c
void InitTab(int *tab, int size){
srand(time(NULL));
for (int i=0; i<size; i++){
*(tab+i) = rand() % 10;
}
}
int MinSumTab(int *min, int *tab, int size){
int total=0;
int minimum = NMAX;
int temp = *min;
for (int i=0; i<size; i++){
total += *(tab+i);
}
for (int i=0; i<size; i++){
if(*(tab+i)<minimum){
minimum = *(tab+i);
}
}
*min = minimum;
return total;
}
So the expected result here is that the sum is printed (which it is) and the minimum value of the array is printed (which it is not). Every single time the min variable equals 8 and I've no idea how to actually change the value of min from within that function.
Please help as my brain has no more capacity for rational thought, it's been 1.5 hrs and no solution in sight. Thanks
Looks like a small mistake:
You initialize minimum with NMAX, which I assume is 8 (the size of the array). 99.9% of the random numbers will be bigger. So 8 is chosen as the minimum.
What you really want is to initialize it with RAND_MAX – the maximum value rand() can return.
In C order of evaluation and argument passing is undefined.
You can of course the order yourself but it only to feed your curiosity.
#include <stdio.h>
volatile char *message[] = {
"fisrt", "second", "third", "fourth"
};
int print(size_t x)
{
printf("%s\n", message[x]);
return x;
}
int main()
{
printf("%d %d %d %d\n", print(0), print(1), print(2), print(3));
return 0;
}
Note. There is one exception from this rule.
Logical operators are evaluated form the left to the right.
if( x != NULL && *x == 5)is safe because x will not be dereferenced if it is NULL
Given a value N, if we want to make change for N cents, and we have infinite supply of each of S = { S1, S2, .. , Sm} valued coins, how many ways can we make the change? The order of coins doesn’t matter.
I have written below code but it is always returning one less than the actual answer. I want to know if this is the right way of coding up the solution?
#include <stdio.h>
int ways=0;
int remember[100] = {0};
void foo(int coin_denomination[], int size, int sum)
{
int i;
printf("%d\n", sum);
if (sum==0) {
ways++;
return;
}
if (remember[sum]==1)
return;
remember[sum] = 1;
if (sum < 0)
return;
for(i=0;i<size;i++)
foo(coin_denomination, size, sum-coin_denomination[i]);
}
int main()
{
int coin_denomination[] = {1, 2, 3};
int sum = 5;
foo(coin_denomination, sizeof(coin_denomination)/sizeof(coin_denomination[0]), sum);
printf("%d\n", ways);
return 0;
}
You need some change to foo method. Your problem is that with the variable remember you are not counting some solutions. The goal of variable remember is not correct, you are using for not processing the same coin collection multiple times but you are saving only the sum of the coin collection and the sum could be obtained with multiple coin collections (ex: 1 1 1 have same sum that 1 2 when you select the second, remember[3] would be 1 and not be passing this point, missing solution 1 2 2)
Other way of not repeating coin collection is needed, in this case, adding a parameter that represent the index of coin_denomination that is processing and only allow processing of coin after, the problem is solve.
Code (Tested with GCC 4.9.0):
#include <stdio.h>
int ways=0;
void foo(int coin_denomination[], int size, int sum, int coin_idx = 0)
{
if (sum < 0)
return;
int i;
printf("%d\n", sum);
if (sum==0) {
ways++;
return;
}
for(i=coin_idx;i<size;i++)
foo(coin_denomination, size, sum-coin_denomination[i], i);
}
int main()
{
int coin_denomination[] = {1, 2, 3};
int sum = 5;
foo(coin_denomination, sizeof(coin_denomination)/sizeof(coin_denomination[0]), sum);
printf("%d\n", ways);
return 0;
}
#include<stdio.h>
int max = 100;
int main()
{
int a,j;
int * arr = (int*)malloc(sizeof(int)*max);
arr[max-1] = 1;
scanf("%d",&a);
factor( arr, a);
display(arr);
}
int factor( int arr[],int a)
{
if (!a) return;
int i,carry;
for(i=max-1;i>=0;i--)
{
arr[i] = (arr[i]*a) + carry;
carry = arr[i]/10;
arr[i] = arr[i]%10;
}
factor( arr, a-1);
}
int display(int arr[])
{
int i;
for ( i=0; i<max; i++)
{
printf("%d",arr[i]);
}
}
HI this is my program to find the factorial of numbers but its giving wrong answer i dont know why ...???
like when i give input as 13
then according to myprogram 13 is to be treated in array as 1 and 3 but its giving random numbers -1216731443 -121673144 . i think malloc is having problem , but i can't identify it .
thank you
I think the reason why you are getting "random" numbers is because you haven't initialized the carry variable. In the for loop, you are adding the un-initialized value of carry to the array which will cause undefined results.
Jus check out this program.Logically it seems fine but its giving 000000000000000000000 for everything
#include<stdio.h>
void main()
{
int n=25,k=32;
printf("binary equivalent\n");
while(k!=0)
{
if((n>>1&0x01)!=0)
printf("1");
else
printf("0");
k--;
}
}
You don't ever change n.
Don't try and cram everything into one line, be a little more verbose so that things are clearer.
while(k!=0)
{
if((n & 0x01) != 0)
printf("1");
else
printf("0");
k--;
n >>= 1;
}
That is because you don't change n.
For n=25 we have (n>>1)=12 hence it prints zero. And since you don't change n it prints zero for all k.
You can change it in the following way:
#include
void main()
{
int n=25,k=32;
printf("binary equivalent\n");
while(k!=0)
{
if((n & 0x01)!=0)
printf("1");
else
printf("0");
k--;
n = n >> 1;
}
}
However it will print binary presentation in reversed form.
Your n is never getting changed:
if((n>>1&0x01)!=0)
should be
if(n & 0x01)
and add
n>>=1; after k--;
Also this will produce the binary representation in reverse order.
You are not modifying n - every time you compare 0x01 with second bit on n.
You don't change the value of n within the loop. And probably you want to test the least significant bit before shifting.
/*
* Author: Andrey Vlassov
* Date: Thu Apr 19 03:10:49 UTC 2012
*
* Description:
* An expample program demonstrating how
* to convert decimal integer number to
* binary representation
*
* NOTE:
* For simplicity additional check left out
*
*/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char help[] = ">>> Please provide an integer number as argument!!!";
char id[] = "d2b (c) Andrey Vlassov Apr 18, 2012 8:15PM PST";
if( argc < 2 ) {
printf("%s\n", help);
exit(0);
}
printf("\n%s\n\n", id);
int n = atoi(argv[1]);
int i, bites, bits, mask;
printf("Number is %d\n", n);
printf("size: %d bites\n", bites=sizeof(n));
printf("dec: %d\n", n);
printf("hex: %#x\n", n);
printf("oct: %#o\n", n);
printf("bin: b");
bits = bites*8-1;
mask = 0x01 << (bits-1);
for( i=0; i<bits; i++) {
printf("%d", ( n & mask ? 1 : 0 ) );
mask >>= 1;
}
printf("\n\n");
exit(0);
}
i think it will help the result is the same as other poster posted
#include<stdio.h>
int main()
{
int n=25;
int k=32;
printf("binary equivalent\n");
for (int i=0;i<32;i++){
if((n&1)!=0)
printf("1");
else
printf("0");
n>>=1;
}
}
as #falagar said result will be printed in reverse order
// how to print binary number representation of an integer
// using bitwise operators
//
// oon
// 18.04.2013
// Refs
// http://www.cs.northwestern.edu/~wms128/bits.c
// http://www.cs.cmu.edu/~guna/15-123S11/
#include <stdio.h>
#define no_of_bits_in_a_byte 8
#define get_bit(w,i) ((w>>i)&1)
void print_binary(signed int x);
int main()
{
print_binary(2); // 00000000000000000000000000000010
print_binary(-2); // 11111111111111111111111111111110
return 0;
}
void print_binary(signed int x)
{
int i;
int no_of_bytes = sizeof(x);
for (i=no_of_bytes*no_of_bits_in_a_byte-1; i>=0; i--) {
printf("%d",get_bit(x,i));
}
printf("\n");
}
/*
* print_binary2.c
*
* oon
*
* 19.04.2013
*/
// http://www.cs.northwestern.edu/~wms128/bits.c
// http://www.cs.cmu.edu/~guna/15-123S11/
#include <stdio.h>
#define no_of_bits_in_a_byte 8
#define get_bit(w,i) ((w>>i)&1)
void print_binary2(signed int x, unsigned int n);
int check_bits_fit_in_2s_complement(signed int x, unsigned int n);
void main()
{
print_binary2(2,2); // output: The signed integer 2 cannot be represented by 2 bit(s) in two complements form.
print_binary2(2,3); // output: 010
print_binary2(-2,2); // output: 10
print_binary2(-2,3); // output: 110
}
int check_bits_fit_in_2s_complement(signed int x, unsigned int n) {
int mask = x >> 31;
return !(((~x & mask) + (x & ~mask))>> (n + ~0));
}
void print_binary2(signed int x, unsigned int n)
{
// check if x can be represented by n bits in two's complement form.
if (check_bits_fit_in_2s_complement(x,n)) {
int i;
for (i=n-1; i>=0; i--) {
printf("%d",get_bit(x,i));
}
printf("\n");
} else {
printf("The signed integer %d cannot be represented by %u bit(s) in two complements form.\n",x,n);
}
}
The above code shows how to print binary number in two's complement form where n denotes the number of bits.
int binary(int n)
{
if(n/2)
binary(n/2);
printf("%d",n%2);
}
void main()
{
int n;
printf("enter any number");
scanf("%d",&n);
binary(n):
getch();
}
Try this!
#include<iostream>
#include<stack>
using namespace std;
int main(){
stack<int> st;
int n=25, k=32;
while(k!=0){
if((n&0x01)!=0)
st.push(1);
else
st.push(0);
k--;
n=n>>1;
}
while(!st.empty()){
cout<<st.top();
st.pop();
}
}