Why does this not produce an error? - c

I'm confused as to why this does not cause an error.
void f(int I) {
++I;
if (I > INT_MAX) {
printf("OVERFLOW\n");
} else {
printf("NO OVERFLOW\n");
}
}
int main(void) {
f(INT_MAX);
printf("DONE\n");
}
I'm coding in C, and my school defined INT_MAX for us already to be $2^{31} - 1$ I think is what it is.

This can give you NO OVERFLOW on two different routes:
Your compiler has the right to optimize out your if statement. Since nothing of int type can be >INT_MAX, it's always false, thus your if is compiled to a simple printf("NO OVERFLOW\n");.
For the other one you need to know 2-complement. If you add 1 to INT_MAX, it turns around, and becomes the smallest number an int can represent. So 2147483647+1=-2147483648, which doesn't make sense in maths, but here it's a design feature. This makes adding reasonably large negative numbers to positive numbers work well. Just you need to keep in mind to use the proper type to hold your numbers.
(I'm assuming a "normal" 32 bit int, but some architectures use different size, e.g. on AVR8 ints are 16 bit long.)

OVERFLOW will not be printed in your case. What is happening in your case is that: When your I is already at the maximum, and if you further increase it using ++I, it will wrap around to the lowest value. Illustration:
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
void f(int I) {
++I;
printf("\nAfter incrementing I: %d\n", I);
if (I > INT_MAX) {
printf("OVERFLOW\n");
} else {
printf("NO OVERFLOW\n");
}
}
int main(void) {
f(INT_MAX);
printf("DONE\n");
}
Output:
After incrementing I: -2147483648
NO OVERFLOW
DONE

Related

Floating point exception (core dumped) - Non-square numbers finder

i have a problem. I've been making this for hours, and i finally thought i had a draft, i solved a few mistakes i made, but now it's typing out "Floating point exception (core dumped)" when i run it. I was able to solve a few other issues, but I don't think i can get over this one without basically starting from scratch, i have no idea what could be causing this, i wonder if any more knowledgeable people here could take a look and try to spot a possible mistake. My program is supposed to find Non-square numbers - numbers not divisible by squares of whole numbers. It first finds squares to divide by, and then divides Non-square number candidates up to a specified integer. Then it types out all the numbers it finds. I think it's quite possible i've made a mistake in pointer usage, i have not yet quite mastered those, and most likely couldn't solve a related issue anyway.
#include <stdio.h>
#include <limits.h>
#include <math.h>
#include <stdlib.h>
int isNonSq (int a,int sqr) {
int b=0.75*a;
for (int i=2;i<b;i++) {
if (a%sqr[i]==0) return 0;
}
return 1;
}
int main ( void ) {
int a;
int * resNum;
int * sqr;
while (!feof(stdin)) {
if (scanf(" %d",&a)!=1||a<=0) {
printf("Nespravny vstup.\n");
return 0;
} else {
int b, c=1;
b=0.75*a;
resNum=(int)malloc(a*sizeof(resNum));
sqr=(int)malloc(a*sizeof(*sqr));
for (int i=2;i<sqrt(a);i++)
sqr[i]=pow(i,2);
for (int i=1;i<b;i++) {
if (isNonSq(i,sqr)) {
resNum[c]=i;
c++;
}
}
}
}
for (int i=1;i<a;i++) {
printf(" %d",resNum[i]);
}
printf("\n");
free(resNum);
free(sqr);
return 0;
}
This could be occurring because of an NaN or an infinite number, I would recommend you use gdb to figure out what is happening when you run your compiled c code. https://www.cs.swarthmore.edu/~newhall/unixhelp/howto_gdb.php
Goodluck!

Sum of odd numbers from 1 - 100 using RECURSION in C

Trying to figure out where I am going wrong in this code, I realize I keep getting 1 because that's what am I passing in the function but how else can I do this?
#include <stdio.h>
#include <stdlib.h>
int totalOdd();
int main(){
printf("%d\n",totalOdd(1));
}
int totalOdd(int n){
int odd = n;
if(odd >= 100){
return 0;
}
else{
totalOdd(odd+2);
}
return odd;
}
try this one
one :
#include <stdio.h>
#include <stdlib.h>
int totalOdd(int);
int main(){
printf("%d\n",totalOdd(1));
}
int totalOdd(int n)
{
int odd = n;
if(odd > 100){
return 0;
}
else{
return (n+totalOdd(odd+2));
}
}
in your code , addition was missing
#include <stdio.h>
#include <stdlib.h>
int totalOdd();
int main(){
printf("%d\n",totalOdd(1));
}
int totalOdd(int odd){
if(odd >= 100)
return 0;
return (odd + totalOdd(odd + 2));
}
Not a complete answer, because this sounds like homework, but here’s an example of how to write a very similar function, first recursively, and then a more efficient tail-recursive solution.
#include <stdio.h>
#include <stdlib.h>
unsigned long factorial1(const unsigned long n)
{
/* The naive implementation. */
if ( n <= 1U )
return 1; // 0! is the nullary product, 1.
else
return n*factorial1(n-1);
/* Notice that there is one more operation after the call to
* factorial1() above: a multiplication. Most compilers need to keep
* all the intermediate results on the stack and do all the multiplic-
* ations after factorial1(1) returns.
*/
}
static unsigned long factorial_helper( const unsigned long n,
const unsigned long accumulator )
{
/* Most compilers should be able to optimize this tail-recursive version
* into faster code.
*/
if ( n <= 1U )
return accumulator;
else
return factorial_helper( n-1, n*accumulator );
/* Notice that the return value is simply another call to the same function.
* This pattern is called tail-recursion, and is as efficient as iterative
* code (like a for loop).
*/
}
unsigned long factorial2(const unsigned long n)
{
return factorial_helper( n, 1U );
}
int main(void)
{
printf( "%lu = %lu\n", factorial1(10), factorial2(10) );
return EXIT_SUCCESS;
}
Examining the output of both gcc -O -S and clang -O -S on the above code, I see that in practice, clang 3.8.1 can compile both versions to the same optimized loop, and gcc 6.2.0 does not optimize for tail recursion on either, but there are compilers where it would make a difference.
For future reference, you wouldn’t solve this specific problem this way in the real world, but you will use this pattern for other things, especially in functional programming. There is a closed-form solution to the sum of odd numbers in a range. You can use that to get the answer in constant time. You want to look for those whenever possible! Hint: it is the sum, from i = 0 to 100, of 2 i + 1. Do you remember a closed-form formula for the sum of i from 0 to N? 0, 1, 3, 6, 10, 15, ...? The proof is often taught as an example of a proof by induction. And what happens to a sum from 0 to N when you multiply and add by constants?
As for my example, when I have had to compute a factorial function in a real program, it was for the purpose of computing a probability distribution (specifically, the Poisson distribution) for a simulation, and I needed to calculate the factorial of the same numbers repeatedly. Therefore, what I did was store a list of all the factorials I’d already calculated, and look up any number I saw again in that list. That pattern is called memoization.

AntiPalindromic Strings

Actually this is one of the challenges from hackerearth. Here is the link to the problem : https://www.hackerrank.com/challenges/antipalindromic-strings
I somehow figured a way to find the answer. But the problem my code doesn't get accepted due to timeout. Please help me which part makes my code slower.
This is my code :
int anti_palindrome(long int n,long int m,int mod)
{
int prod;
prod=m;
if(n>1)
prod=prod*(m-1);
if(n>2)
{
n=n-2;
while(n)
{
prod=prod*(m-2);
n--;
}
}
return prod%mod;
}
int main()
{
char scanned[1000];
int input = 0;
int T=0;
int T_cur=0;
long int N,M;
char str[1000];
int mod=1000000007;
while(fgets(scanned,1000,stdin))
{
switch(input)
{
case 0: {
T=atoi(scanned);
input=1;
}
break;
case 1: {
T_cur++;
strcpy(str,scanned);
sscanf(str,"%d %d",&N,&M);
//printf("%lf %lf\n",N,M);
printf("%d\n",anti_palindrome(N,M,mod));
}
break;
}
if(T_cur==T)
break;
}
return 0;
}
Any one run of the program may need to process up to 105 N, M pairs, with N and M each between 1 and 109.
Please help me which part makes my code slower.
There aren't many parts to consider. Generally speaking, I/O is much slower than computation, but you haven't any more I/O than is needed, so let's disregard that for the moment.
Consider, then, your anti_palindrome() function. In the general case, it loops N times, performing three arithmetic operations and two assignments in each iteration. That's not expensive on a per-iteration basis, but you may have a billion iterations per test case, and ten thousand test cases, for a total of around 5x1014 mixed operations. That number of operations is going to take more than a few seconds.
While I'm at it, I observe that your algorithm is wrong anyway. You are supposed to report the answer modulo 109 + 7, but long before you get to the end of the computation, you will have overflowed the prod variable. The resulting behavior is undefined. If prod had an unsigned type then the behavior would be defined, but still wrong. Switching to pow() instead of a loop would improve the performance enormously, but would not solve this problem. You need something cleverer.
As m-2 is constant, write m= m-2; before the loop. Now, what remains is that n times prod=prod*m; is executed. This is equivalent to prod= prod*pow(m,n); The math library may have an efficient implementation of pow() that will prevent your timing issue.
In C you may have to cast the parameters to double, and the return value to long int.
int anti_palindrome(long int n,long int m,int mod)
{
int prod;
prod=m;
if(prod>1)
prod=prod*(m-1);
if(prod>2)
{
n=n-2;
m=m-2;
prod= prod*pow(m,n);
}
return prod%mod;
}

Why am I getting this strange output on this simple C program? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am working on a personal project where one part of it deals with counting squares and cubes under a certain bound (in this case 10,000). So, I wrote a simple C program I thought would work to verify my results. Here is the little program I put together to see all of the cubes:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main() {
double i;
int cubes = 0;
for (i = 1; i < 10000; i++) {
if ( i == cbrt(i) * cbrt(i) * cbrt(i) ) {
printf("%f --- %f\n",i, cbrt(i));
cubes++;
}
}
printf("%i\n", cubes);
return 0;
}
I got the (incorrect) output : 24. If you want to look at this see the problem look at numbers 15 and 20 on the output. Why I am getting the wrong answer (the correct answer is 21) is an entirely different matter. My question arose when I was messing around with my code to try and fix this and I temporarily changed it to this:
int main() {
double i;
int cubes = 0;
for (i = 1; i < 10000; i++) {
double temp = (cbrt(i) * cbrt(i) * cbrt(i));
if ( i == temp ) {
printf("%f -> %f\n", i, temp);
cubes++;
}
}
printf("%i\n", cubes);
return 0;
}
Now, the program is printing every number between 1 and 9999. So, am I missing something ridiculously easy or what is going on? All I did was instead of having cbrt(i)*cbrt(i)*cbrt(i) in the if conditional I set a double variable equal to result and placed that in the conditional. Why is my program doing this?
I am not sure why this got down voted. I feel like this is a legitimate question. Sorry S.O. community...
double cbrt(double x) returns the closest representable cubic root of x.
The inexactness of the result, then cubed, may not exactly equal 'x' again.
Why 2nd program differs:
C is not obliged to perform double math only to double precision. It may use wider (long double). Depending on many things, the 2nd code appears to have done more in long double than the first. With the extra precision, its easy to see that the results, rounded to double appear exact.
C11dr §5.2.4.2.2 9 Except for assignment and cast (which remove all extra range and precision), the values yielded by operators with floating operands and values subject to the usual arithmetic conversions and of floating constants are evaluated to a format whose range and precision may be greater than required by the type.
Why a typical program run (of either code) produces a result of about 3333.
Consider the double numbers from 2 to 4 and 8 to 64. double numbers are logarithmically distributed. There are as many different double from 2 to 4 as 8 to 16 as 16 to 32 as 32 to 64.
So now all 3 sets from 8 to 64 have a cube root of some answer in the 1 set of 2 to 4. Now if we cube the numbers 2 to 4, we get answers in the range 8 to 64. 1 set of numbers mapping into 3 sets. The round trip is not exact. See Pigeonhole principle. IOW: On average, 3 numbers in the range 8 to 64 have the same cubic root. Then the cube of that root will be 1 of the 3 original.
To find the count of the perfect integer cubes 0 to N
unsigned Perfect_Cube_Count(unsigned n) {
if (n == 0)
return 1;
unsigned i;
// overflow not possible
for (i = 0; i*i < n/i; i++);
return i;
}
Or
// valid for 0 <= x <= something_well_over_1e9
double Perfect_Cube_Count_d(double x) {
double y = cbrt(x);
return floor(y) + 1;
}
You probably want, as Andrew guessed, whole-number cube roots. Float math is quite tricky because of rounding errors. Generally you cannot rely on equality but must compare with an error margin.
To solve your problem though I'd construct the 21 cubes beforehand and then iterate over integers, comparing against the pre-constructed cubes. Or is that cheating? ;-)
In Samuel Becket's novel Watt there is a chapter about a Scottish "Math genius" who could in his head compute all integer third roots of integer cubes up to 10000 or so, too!
My uess, is your compiler does an optimization in the second case, eli inating cbrt calls. It just says the result of cbrt is strictly defined by the standard, so it might as well be always thte case that (i == temp)
You can twak this by some command line arguments, and force it to do exactly what is written in the code. As I recall, this should thhe default thing to do for C compilers regarding float arthimetic, but your compiler may think it is smarter than you or something.
EDIT
And yes, this code has nothing to do with finding perfect cubes...
EDIT
Totally not an answer to the question, but as a quick exercise, this I wrote this:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
static unsigned long count_cubes(unsigned long max_n)
{
unsigned long n = 1;
while (n*n*n <= max_n) {
++n;
}
return n-1;
}
int main(int argc, char **argv)
{
unsigned long max_n;
char *p;
if (argc < 2) {
return EXIT_FAILURE;
}
max_n = strtoul(argv[1], &p, 10);
if (max_n < 1 || max_n == ULONG_MAX) {
return EXIT_FAILURE;
}
printf("%lu\n", count_cubes(max_n));
return EXIT_SUCCESS;
}
Note: no need for floating point arithmetic
EDIT
Sorry, I really got into this...
This one can be a bit faster:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <math.h>
static unsigned long count_cubes(unsigned long max_n)
{
unsigned long n;
if (max_n < 256) {
n = 1;
}
else {
n = cbrtl(max_n) - 1;
}
while (n*n*n <= max_n) {
++n;
}
return n-1;
}
int main(int argc, char **argv)
{
unsigned long max_n;
char *p;
if (argc < 2) {
return EXIT_FAILURE;
}
max_n = strtoul(argv[1], &p, 10);
if (max_n < 1 || max_n == ULONG_MAX) {
return EXIT_FAILURE;
}
printf("%lu\n", count_cubes(max_n));
return EXIT_SUCCESS;
}
EDIT ( last time, I promise... )
To show an explanation of my little loop above, starting at cbrt(max_n)-1, I tried the one suggested by #chux , here are some results with slightly larger numbers:
PerfectCubes(18446724184312856125) == 2642246
which is fine but also
PerfectCubes(18446724184312856125-10) == 2642246
which is totally not fine, since 18446724184312856125 == 2642245^3 , meaning there are 2642245 perfect cubes <= 18446724184312856125-10 .
This also results from inaccuracies in floating point representation. You can try it for yourself, if your computer is somewhat similar to mine:
printf("%f\n", cbrt( 2642245UL * 2642245UL * 2642245UL));
/* prints 2642245.000000 */
printf("%f\n", cbrt( 2642245UL * 2642245UL * 2642245UL - 10UL));
/* prints 2642245.000000 */
These two numbers clearly don't have the same cubic root, yet cbrt returns the same results. In this case, floor doesn't help either. Anyways, one always needs to be very careful using floating point arithmetics. And now I really should go to sleep.

a few bugs while executing the program

I want to write a program to see if an integer is the power of another integer(true return 1 and false return 0). And the code is as follows:
#include <stdio.h>
#include <math.h>
int cal_base_power(int);
int main()
{
int x,r;
printf("Please input an integer\n");
scanf("%d\n",&x);
r=cal_base_power(x);
printf("result is %d\n",r);
}
int cal_base_power(int input)
{
int i=2;
double a=pow(input,(double)1/i);
while (a>=2)
{
if ((double)a==(int)a)
return 1;
i++;
a=pow(input,(double)1/i);
}
return 0;
}
It is ok with 4,8,125 some cases like these. But failed when input 216 and 343. Also it will not automatically output 0 and 1. I must input some random characteristics before the result 0 or 1 comes out.
Can anyone help me? I know it is quite easy. But I really need your help
You can't do equality comparisons on floating-point.
(double)a==(int)a
Due to round-off error, a might not be exactly an integer even though it's supposed to be.
EDIT:
There's two ways to do this:
Allow tolerance on the comparison: fabs(a - (int)a) < 0.0001 (or something like that, you'll need to tweak the threshold.)
Round a to the nearest integer and power it back up (using integers only) to see if it matches the input.

Resources