I made a simple program in C that finds if a number is prime. I am new to C and decided to try to use scanf instead of hardcoded numbers to check. When I run my code:
#include <stdio.h>
typedef int bool;
#define true 1
#define false 0
int main(){
//I am going to check if the "checking" variable is a prime
int checking;
scanf("%d",checking);
//"stopper" is where the for loop will stop
int stopper = checking**0.5 + 1;
//"found" will show if I have found something bad
bool found = false;
for (int i = 2; i < stopper; i++)
{
if (checking % i == 0){found = true; break;}
}
if (!found) {printf("it is prime");}
else {printf("it is not prime");}
}
when I try to compile this with TCC it gives the error (primes.c is the name of the document)
primes.c:12 error: pointer expected
I don't know how to fix this.
EDIT: I just made stopper = checking/2 and the program crashes
int stopper = checking**0.5 + 1;
line 12... what do you expect the ** operator to do?
A * typically performs a multiply, or dereferences a pointer.
The compiler could be interpreting it as follows:
int stopper = checking * (*0.5) + 1;
Of course, trying to dereference a float (*0.5) is bad / impossible, hence the error.
Did you mean:
instead of **, you meant * (multiply)
instead of ** (not a C operator), you meant pow() (raise to the power of)
You also need to be specific - even if you're an expert at precedance, the reader may not be, and you may well be wrong.
If you're not sure what's going on, use braces to be specific, which of the following do you mean?
int stopper = checking * (0.5 + 1);
int stopper = (checking * 0.5) + 1;
int stopper = pow(checking, 0.5) + 1;
int stopper = pow(checking, 0.5 + 1);
If you are indeed after the square root, then as #JeremyP says, invert your thinking - multiply is much less costly than pow():
for (int i = 2; i * i <= checking; i++)
You have two problems in your program:
(1) Replace
int stopper = checking**0.5 + 1;
with
int stopper = checking*0.5 + 1;
(2) Replace
scanf("%d",checking);
with
scanf("%d",&checking);
You should be good to after these corrections.
There's no built in operator to raise a number to the power of another number. There is a function to do that - also a square root function but you don't need them (see below).
x**y
is parsed as
x* (*y)
which is where your pointer error comes from
Instead of trying to find the square root, come at it from the other direction, change your for loop like this
for (int i = 2; i * i <= checking; i++)
Also, as others have said, the scanf is wrong.
scanf("%d",&checking);
// ^- scanf needs a pointer to an int.
Firstly, the scanf is wrong.
Use scanf("%d",&checking);
For finding the square root use math.h library for sqrt function.
int stopper = sqrt(checking) + 1;
There were a lot of typing mistakes in your code. Please, correct your syntax before asking a question.
Ideone link for code
Related
I'm trying to increase 0.001f in a loop, so in loop 1 the value is 0.001f, in loop 2 the value is 0.002f
This is what I have (doesn't work since it doesn't include the i in the value and it's not correct):
for (int i = 0; i < 34; i++) {
GRAPHICS::DRAW_RECT(0.825f, ((maxOptions * 0.000f++) + 0.1765f), 0.23f, 0.035f, scrollerColor.r, scrollerColor.g, scrollerColor.b, scrollerColor.a); // Scroller
}
I have tried making a buffer like so, but as expected that didn't work:
int buffer[10];
sprintf(buffer, "0.00%if", i);
How would I do this? ANswers are appreciated!
0.000f++ is invalid syntax, as the postincrement operator cannot be used on constants. It can only be used on an lvalue (i.e. the name of a variable or an expression that represents one).
Assuming you want this value to range from 0.001 to 0.034 you would multiply 0.001 by the loop index, changing the loop to go from 1 to 34 instead of 0 to 33.
for (int i = 1; i <= 34; i++) {
GRAPHICS::DRAW_RECT(0.825f, ((maxOptions * 0.001f * i) + 0.1765f),
0.23f, 0.035f, scrollerColor.r, scrollerColor.g,
scrollerColor.b, scrollerColor.a); // Scroller
}
The variable i is never used inside your loop. Maybe you could tell us where you want to use it, or add more context to the question?
But here's my first raw attempt at an answer anyway:
for (float i = 0; i < 0.034f; i += 0.001f) {
GRAPHICS::DRAW_RECT(0.825f, ((maxOptions * 0.000f++ /* This part has an issue and I can't understand what you mean by it*/) + 0.1765f), 0.23f, 0.035f, scrollerColor.r, scrollerColor.g, scrollerColor.b, scrollerColor.a); // Scroller
}
Due to the way your processor handles floating point arithmetic, this code can result in one more or less loop as pointed out by dbush (thanks!)
You can fix it as follows:
// Include math.h at the top of your code.
for (float i = 0; fabs(i - 0.034f) > 0.0001; i += 0.001f) {
GRAPHICS::DRAW_RECT(0.825f, ((maxOptions * 0.000f++ /* This part has an issue and I can't understand what you mean by it*/) + 0.1765f), 0.23f, 0.035f, scrollerColor.r, scrollerColor.g, scrollerColor.b, scrollerColor.a); // Scroller
}
I'm stuck with a program where just having a printf statement is causing changes in the output.
I have an array of n elements. For the median of every d consecutive elements, if the (d+1)th element is greater or equals to twice of it (the median), I'm incrementing the value of notifications. The complete problem statement might be referred here.
This is my program:
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
#define RANGE 200
float find_median(int *freq, int *ar, int i, int d) {
int *count = (int *)calloc(sizeof(int), RANGE + 1);
for (int j = 0; j <= RANGE; j++) {
count[j] = freq[j];
}
for (int j = 1; j <= RANGE; j++) {
count[j] += count[j - 1];
}
int *arr = (int *)malloc(sizeof(int) * d);
float median;
for (int j = i; j < i + d; j++) {
int index = count[ar[j]] - 1;
arr[index] = ar[j];
count[ar[j]]--;
if (index == d / 2) {
if (d % 2 == 0) {
median = (float)(arr[index] + arr[index - 1]) / 2;
} else {
median = arr[index];
}
break;
}
}
free(count);
free(arr);
return median;
}
int main() {
int n, d;
scanf("%d %d", &n, &d);
int *arr = malloc(sizeof(int) * n);
for (int i = 0; i < n; i++) {
scanf("%i", &arr[i]);
}
int *freq = (int *)calloc(sizeof(int), RANGE + 1);
int notifications = 0;
if (d < n) {
for (int i = 0; i < d; i++)
freq[arr[i]]++;
for (int i = 0; i < n - d; i++) {
float median = find_median(freq, arr, i, d); /* Count sorts the arr elements in the range i to i+d-1 and returns the median */
if (arr[i + d] >= 2 * median) { /* If the (i+d)th element is greater or equals to twice the median, increments notifications*/
printf("X");
notifications++;
}
freq[arr[i]]--;
freq[arr[i + d]]++;
}
}
printf("%d", notifications);
return 0;
}
Now, For large inputs like this, the program outputs 936 as the value of notifications whereas when I just exclude the statement printf("X") the program outputs 1027 as the value of notifications.
I'm really not able to understand what is causing this behavior in my program, and what I'm missing/overseeing.
Your program has undefined behavior here:
for (int j = 0; j <= RANGE; j++) {
count[j] += count[j - 1];
}
You should start the loop at j = 1. As coded, you access memory before the beginning of the array count, which could cause a crash or produce an unpredictable value. Changing anything in the running environment can lead to a different behavior. As a matter of fact, even changing nothing could.
The rest of the code is more difficult to follow at a quick glance, but given the computations on index values, there may be more problems there too.
For starters, you should add some consistency checks:
verify the return value of scanf() to ensure proper conversions.
verify the values read into arr, they must be in the range 0..RANGE
verify that int index = count[ar[j]] - 1; never produces a negative number.
same for count[ar[j]]--;
verify that median = (float)(arr[index] + arr[index - 1]) / 2; is never evaluated with index == 0.
Your program has undefined behavior (at several occasions). You really should be scared (and you are not scared enough).
I'm really not able to understand what is causing this behavior in my program
With UB, that question is pointless. You need to dive into implementation details (e.g. study the generated machine code of your program, and the code of your C compiler and standard library) to understand anything more. You probably don't want to do that (it could take years of work).
Please read as quickly as possible Lattner's blog on What Every C Programmer Should Know on Undefined Behavior
what I'm missing/overseeing.
You don't understand well enough UB. Be aware that a programming language is a specification (and code against it), not a software (e.g. your compiler). Program semantics is important.
As I said in comments:
compile with all warnings and debug info (gcc -Wall -Wextra -g with GCC)
improve your code to get no warnings; perhaps try also another compiler like Clang and work to also get no warnings from it (since different compilers give different warnings).
consider using some version control system like git to keep various variants of your code, and some build automation tool.
think more about your program and invariants inside it.
use the debugger (gdb), in particular with watchpoints, to understand the internal state of your process; and have several test cases to run under the debugger and without it.
use instrumentation facilities such as the address sanitizer -fsanitize=address of GCC and tools like valgrind.
use rubber duck debugging methodology
sometimes consider static source code analysis tools (e.g. Frama-C). They require expertise to be used, and/or give many false positives.
read more about programming (e.g. SICP) and about the C Programming Language. Download and study the C11 programming language specification n1570 (and be very careful about every mention of UB in it). Read carefully the documentation of every standard or external function you are using. Study also the documentation of your compiler and of other tools. Handle error and failure cases (e.g. calloc and scanf can fail).
Debugging is difficult (e.g. because of the Halting Problem, of Heisenbugs, etc...) - but sometimes fun and challenging. You can spend weeks on finding one single bug. And you often cannot understand the behavior of a buggy program without diving into implementation details (studying the machine code generated by the compiler, studying the code of the compiler).
PS. Your question shows a wrong mindset -which you should improve-, and misunderstanding of UB.
I would like to find all the primes within 100. Here is my codes.
// Find all the prime number within 100.
#include<stdio.h>
#include<math.h>
#include<stdbool.h>
int main() {
int i,n;
int j = 0;
for ( n = 2; n <= 100; ++n) {
bool isPrime = true;
for (i = 2; i <= sqrt(float(n)); ++i) {
if(n % i == 0) {
isPrime = false;
break;
}
}
if(isPrime) {
++j;
printf("%d is a prime number\n",n);
}
}
printf("The total number of prime number within 100 is %d\n",j);
return 0;
}
When compile it, there is one error.
prime.c:14:8: error: expected expression before ‘float’
m = float(n);
^
Could anyone help solve this problem? Thanks.
You're using the wrong syntax when casting (you're using one of C++'s many styles of casting, but for C there is only one way). Change:
sqrt(float(n))
to
sqrt((float)n)
Note however that sqrt takes a double, so strictly speaking this should be:
sqrt((double)n)
Note also that the cast is not necessary, and you can just write:
sqrt(n)
Change this
sqrt(float(n))
to this
sqrt((float)n)
You want to cast n to float.
You should use this function:
float sqrtf (float x);
which in C99 receives a float as an argument. Otherwise, it would be better to cast into double (if you use sqrt()).
sqrt-ref
What you have written:
float(n)
is like saying that float is a name of a function and you pass to it the parameter n.
Notice, that in your case, you don't need casting, since it's going to be performed automatically (to float if you use sqrtf() or to double if you use sqrt()).
Other notes, irrelevant with your syntax error.
Why not start the loop from 3 and increase the counter by two? If you think about it, this will faster and will produce the same results. If you want to test yourself, check my example here.
Also, what I had found pretty exciting when I was searching for primes, is the sieve of Eratosthene's (Κόσκινο του Ερατοσθένη) . Here is an example of it.
If you want to cast n to a float, use (float)n.
Just do:
sqrt(n);
You'll be having the exam same result as the casting for your case.
I am unable to understand why i am getting runtime error with this code. Problem is every number >=6 can be represented as sum of two prime numbers.
My code is ...... Thanks in advance problem link is http://poj.org/problem?id=2262
#include "stdio.h"
#include "stdlib.h"
#define N 1000000
int main()
{
long int i,j,k;
long int *cp = malloc(1000000*sizeof(long int));
long int *isprime = malloc(1000000*sizeof(long int));
//long int *isprime;
long int num,flag;
//isprime = malloc(2*sizeof(long int));
for(i=0;i<N;i++)
{
isprime[i]=1;
}
j=0;
for(i=2;i<N;i++)
{
if(isprime[i])
{
cp[j] = i;
j++;
for(k=i*i;k<N;k+=i)
{
isprime[k] = 0;
}
}
}
//for(i=0;i<j;i++)
//{
// printf("%d ",cp[i]);
//}
//printf("\n");
while(1)
{
scanf("%ld",&num);
if(num==0) break;
flag = 0;
for(i=0;i<j&&num>cp[i];i++)
{
//printf("%d ",cp[i]);
if(isprime[num-cp[i]])
{
printf("%ld = %ld + %ld\n",num,cp[i],num-cp[i]);
flag = 1;
break;
}
}
if(flag==0)
{
printf("Goldbach's conjecture is wrong.\n");
}
}
free(cp);
free(isprime);
return 0;
}
Two possibilities immediately spring to mind. The first is that the user input may be failing if whatever test harness is being used does not provide any input. Without knowing more detail on the harness, this is a guess at best.
You could check that by hard-coding a value rather than accepting one from standard input.
The other possibility is the rather large memory allocations being done. It may be that you're in a constrained environment which doesn't allow that.
A simple test for that is to drop the value of N (and, by the way, use it rather than the multiple hardcoded 1000000 figures in your malloc calls). A better way would be to check the return value from malloc to ensure it's not NULL. That should be done anyway.
And, aside from that, you may want to check your Eratosthenes Sieve code. The first item that should be marked non-prime for the prime i is i + i rather than i * i as you have. I think it should be:
for (k = i + i; k < N; k += i)
The mathematical algorithm is actually okay since any multiple of N less than N * N will already have been marked non-prime by virtue of the fact it's a multiple of one of the primes previously checked.
Your problem lies with integer overflow. At the point where N becomes 46_349, N * N is 2_148_229_801 which, if you have a 32-bit two's complement integer (maximum value of 2_147_483_647), will wrap around to -2_146_737_495.
When that happens, the loop keeps going since that negative number is still less than your limit, but using it as an array index is, shall we say, inadvisable :-)
The reason it works with i + i is because your limit is well short of INT_MAX / 2 so no overflow happens there.
If you want to make sure that this won't be a problem if you get up near INT_MAX / 2, you can use something like:
for (k = i + i; (k < N) && (k > i); k += i)
That extra check on k should catch the wraparound event, provided your wrapping follows the "normal" behaviour - technically, I think it's undefined behaviour to wrap but most implementations simply wrap two positives back to a negative due to the two's complement nature. Be aware then that this is actually non-portable, but what that means in practice is that it will only work on 99.999% of machines out there :-)
But, if you're a stickler for portability, there are better ways to prevent overflow in the first place. I won't go into them here but to say they involve subtracting one of the terms being summed from MAX_INT and comparing it to the other term being summed.
The only way I can get this to give an error is if I enter a value greater than 1000000 or less than 1 to the scanf().
Like this:
ubuntu#amrith:/tmp$ ./x
183475666
Segmentation fault (core dumped)
ubuntu#amrith:/tmp$
But the reason for that should be obvious. Other than that, this code looks good.
Just trying to find what went wrong!
If the sizeof(long int) is 4 bytes for the OS that you are using, then it makes this problem.
In the code:
for(k=i*i;k<N;k+=i)
{
isprime[k] = 0;
}
Here, when you do k = i*i, for large values if i, the value of k goes beyond 4 bytesand get truncated which may result in negative numbers and so, the condition k<N is satisfied but with a negative number :). So you get a segmentation fault there.
It's good that you need only i+i, but if you need to increase the limit, take care of this problem.
char byte_to_ascii(char value_to_convert, volatile char *converted_value) {
if (value_to_convert < 10) {
return (value_to_convert + 48);
} else {
char a = value_to_convert / 10;
double x = fmod((double)value_to_convert, 10.0);
char b = (char)x;
a = a + 48;
b = b + 48;
*converted_value = a;
*(converted_value+1) = b;
return 0;
}
}
The purpose of this function is to take an unsigned char value of 0 through 99 and return either it's ascii equivalent in the case it is 0-9 or manipulate a small global character array that can be referenced from the calling code following function completion.
I ask this question because two compilers from the same vendor interpret this code in different ways.
This code was written as a way to parse address bytes sent via RS485 into strings that can easily be passed to a send-lcd-string function.
This code is written for the PIC18 architecture (8 bit uC).
The problem is that the free/evaluation version of a particular compiler generates perfect assembly code that works while suffering a performance hit, but the paid and supposedly superior compiler generates code more efficiently at the expense of being able reference the addresses of all my byte arrays used to drive the graphics on my lcd display.
I know I'm putting lots of mud in the water by using a proprietary compiler for a less than typical architecture, but I hope someone out there has some suggestions.
Thanks.
I would definitely avoid using floating point anything on a PIC. And I would -try not to- use any divisions. How many times do you see sending a non-ascii char to the LCD? Can you save it to the LCD's memory and then call it by it's memory position?
Here's what a divide by 10 looks like in my code, note the 17 cycles it needs to complete. Think about how long that will take, and make sure there is nothing else waiting on this.
61: q = d2 / 10;
01520 90482E mov.b [0x001c+10],0x0000
01522 FB8000 ze 0x0000,0x0000
01524 2000A2 mov.w #0xa,0x0004
01526 090011 repeat #17
01528 D88002 div.uw 0x0000,0x0004
0152A 984F00 mov.b 0x0000,[0x001c+8]
If you do a floating point anything in your code, look in the program memory after you've compiled it, on the Symbolic tab (so you can actually read it) and look for the floating point code that will need to be included. You'll find it up near the top (depending on your code), soon(ish) after the _reset label.
Mine starts at line number 223 and memory address of 001BC with _ floatsisf, continues through several additional labels (_fpack, _divsf3, etc) and ends in _funpack, last line at 535 and memory address 0042C. If you can handle (42C-1BC = 0x270 =) 624 bytes of lost program space, great, but some chips have just 2k of space and that's not an option.
Instead of floating point, if it's possible, try to use fixed point arithmetic, in base 2.
As far as not being able to reference all the byte arrays in your LCD, have you checked to make sure that you're not trying to send a null (which is a fine address) but it get's stopped by code checking for the end of an ascii string? (it's happened to me before).
modulo and integer division can be very very expensive. I have do not know about your particular architecture, but my guess it is expensive there as well.
If you need both, division and modulo, do one of them and get the other one by multiplication/difference.
q =p/10;
r = p - q*10;
I'd probably write that as:
char byte_to_ascii(char value_to_convert, volatile char *converted_value)
{
if (value_to_convert < 10) {
return value_to_convert + '0';
} else {
converted_value[0] = (value_to_convert / 10) + '0';
converted_value[1] = (value_to_convert % 10) + '0';
return 0;
}
}
Is it poor form to convert to floating, call fmod, and convert to integer, instead of just using the % operator? I would say yes. There are more readable ways to slow down a program to meet some timing requirement, for example sleeping in a for loop. No matter what compiler or what tweaking of assembly code or whatever else, this is a highly obfuscated way to control the execution speed of your program, and I call it poor form.
If perfect assembly code means that it works right but it's even slower than the conversions to floating point and back, then use integers and sleep in a for loop.
As for the imperfect assembly code, what's the problem? "at the expense of being able reference the addresses of all my byte arrays"? It looks like type char* is working in your code, so it seems that you can address all your byte arrays the way the C standard says you can. What's the problem?
Frankly, I would say yes..
If you wanted b to be the remainder, either use MOD or roll-your-own:
char a = value_to_convert / 10;
char b = value_to_convert - (10 * a);
Conversion to/from floats is never the way to do things, unless your values really are floats.
Furthermore, I would strongly recommend to stick to the convention of explicitly referring to your datatypes as 'signed' or 'unsigned', and leave the bare 'char' for when it actually is a character (part of a string). You are passing in raw data, which I feel should be an unsigned char (assuming of course, that the source is unsigned!). It is easy to forget if something should be signed/unsigned, and with a bare char, you'll get all sorts of roll-over errors.
Most 8-bit micros take forever for a multiply (and more than forever for a divide), so try and minimise these.
Hope this helps..
The code seems to be doing two very different things, depending on whether it's given a number in the range 0-9 or 10-99. For that reason, I would say that this function is written in poor form: I would split your function into two functions.
Since we're discussing divisions by 10 here..
This is my take. It only simple operations and does not even need wide registers.
unsigned char divide_by_10 (unsigned char value)
{
unsigned char q;
q = (value>>1) + (value>>2);
q += (q>>4);
q >>= 3;
value -= (q<<3)+q+q;
return q+((value+6)>>4);
}
Cheers,
Nils
It is typical for optimizers to do unwanted thingies from time to time if you poke around in the internals.
Is your converted_value a global value or otherwise assigned in such a fashion that the compiler knows not to touch it?
PIC's don't like doing pointer arithmetic.
As Windows programmer points out, use the mod operator (see below.)
char byte_to_ascii(char value_to_convert, volatile char *converted_value) {
if (value_to_convert < 10) {
return (value_to_convert + 48);
} else {
char a = value_to_convert / 10;
char b = value_TO_convert%10;
a = a + 48;
b = b + 48;
*converted_value = a;
*(converted_value+1) = b;
return 0;
}
}
Yes, I believe that your function:
char byte_to_ascii(char value_to_convert, volatile char *converted_value) {
if (value_to_convert < 10) {
return (value_to_convert + 48);
} else {
char a = value_to_convert / 10;
double x = fmod((double)value_to_convert, 10.0);
char b = (char)x;
a = a + 48;
b = b + 48;
*converted_value = a;
*(converted_value+1) = b;
return 0;
}
}
is in poor form:
Don't use decimal numbers for ASCII chars, use the character, i.e. '#' instead of 0x40.
There is no need for using the fmode function.
Here is my example:
// Assuming 8-bit octet
char value;
char largeValue;
value = value_to_convert / 100;
value += '0';
converted_value[0] = value;
largeValue = value_to_convert - value * 100;
value = largeValue / 10;
value += '0';
converted_value[1] = value;
largeValue = largeValue - value * 10;
value += '0';
converted_value[2] = value;
converted_value[3] = '\0'; // Null terminator.
Since there are only 3 digits, I decided to unroll the loop. There are no branches to interrupt the prefetching of instructions. No floating point exceptions, just integer arithmetic.
If you leading spaces instead of zeros, you can try this:
value = (value == 0) ? ' ' : value + '0';
Just to be a nitwitt, but multiple return statements from the same function can be considered bad form (MISRA).
Also, some of the discussions above are on the limit of permature optimizations. Some tasks must be left to the compiler. However, in such a minimalistic embedded environment, these tricks may be valid still.