Reversing numbers in C without using built in reverse function - c

I've been given a problem in class and to solve it I can't use the built in functions that already exist in c. It has to be an algorithm that performs the action. My function is below:
int reverseDigits(int userNumber)
{
int rev1, rev2, rev3, rev4, reverseNumber;
rev1 = userNumber/1000;
rev2 = (userNumber - (rev1 * 1000)) / 100;
rev3 = (userNumber - ((rev1 * 1000) + ( rev2 * 100))) / 10;
rev4 = (userNumber - ((rev1 *1000) + (rev2 * 100) + (rev3 * 10))) / 1;
if (rev1 == 0 && rev2 >= 1)
{
reverseNumber = ((rev2 *100) + (rev3 *10) + (rev1 * 1));
return reverseNumber;
}
else if (rev2 == 0 && rev3 >= 1)
{
reverseNumber = ((rev3 * 10) + (rev1 * 1));
}
else if (rev3 == 0 && rev4 >= 1)
{
reverseNumber = (rev4 * 1);
}
else
{
reverseNumber = ((rev4 * 1000) + (rev3 * 100) + (rev2 * 10) + (rev1 * 1));
return reverseNumber;
}
}
The function gets a user input and reverses it. My problem is that when given any number with less than 4 digits (It's only supposed to receive 4) the function returns them correctly but it adds zeros. For instance I send it 678 it will return 8760 or 57 would be 7500. Thanks for any help.

This will work up to 9 digits.
int reverse(int num)
{
int res = 0, tmp;
while(num != 0)
{
tmp = num % 10;
res = res*10 + tmp;
num /= 10;
}
return res;
}

The problem is in the invalid set of if-else statements.
Using your approach the program can look like
#include <stdio.h>
int reverseDigits( int userNumber )
{
int rev1, rev2, rev3, rev4, reverseNumber;
rev1 = userNumber / 1000;
rev2 = ( userNumber - ( rev1 * 1000 ) ) / 100;
rev3 = ( userNumber - ( ( rev1 * 1000 ) + ( rev2 * 100 ) ) ) / 10;
rev4 = ( userNumber - ( ( rev1 * 1000 ) + ( rev2 * 100 ) + ( rev3 * 10 ) ) ) / 1;
if ( rev1 != 0 )
{
reverseNumber = ( rev1 * 1 ) + ( rev2 * 10 ) + ( rev3 * 100 ) + ( rev4 * 1000 );
}
else if ( rev2 != 0 )
{
reverseNumber = ( rev2 * 1 ) + ( rev3 * 10 ) + ( rev4 * 100 );
}
else if ( rev3 != 0 )
{
reverseNumber = ( rev3 * 1 ) + ( rev4 * 10 );
}
else
{
reverseNumber = ( rev4 * 1 );
}
return reverseNumber;
}
int main( void )
{
for ( unsigned int x = 0, n = 1000; n != 0; n /= 10 )
{
x += n;
printf( "%d\t%d\n", x, reverseDigits( x ) );
}
return 0;
}
Its output is
1000 1
1100 11
1110 111
1111 1111

This should do:
int main()
{
int num,i=0;
scanf("%d",&num);
int digit[4]={0};
int num_digits=0;
while(num!=0)
{
digit[num_digits] = num%10;
num = num/10;
num_digits++;
}
for(i=0;i<num_digits;i++)
{
printf("%d",digit[i]);
}
return 0;
}
This can help you edit any number, with any number of digits. Just increase the array size of digit.
Edit :Iterator mistaked edited.

Errors in posted code
The computation under the first if clause is wrong. Instead of
reverseNumber = ((rev2 *100) + (rev3 *10) + (rev1 * 1));
it needs to be
reverseNumber = ((rev4 *100) + (rev3 *10) + (rev2 * 1));
The computation under the first else if clause is wrong. Instead of
reverseNumber = ((rev3 * 10) + (rev1 * 1));
it needs to be
reverseNumber = ((rev4 * 10) + (rev3 * 1));
You are missing return statements in the two else if clauses. As a consequence, if your program gets into those clauses, no return statement is executed and the program has undefined behavior. You can resolve that by removing the return statements you have now and adding a return statement at the end.
if (rev1 == 0 && rev2 >= 1)
{
reverseNumber = ((rev4 *100) + (rev3 *10) + (rev2 * 1));
}
else if (rev2 == 0 && rev3 >= 1)
{
reverseNumber = ((rev4 * 10) + (rev3 * 1));
}
else if (rev3 == 0 && rev4 >= 1)
{
reverseNumber = (rev4 * 1);
}
else
{
reverseNumber = ((rev4 * 1000) + (rev3 * 100) + (rev2 * 10) + (rev1 * 1));
}
return reverseNumber;
A recursive solution
If you are able to use recursive functions, you can use:
int reverseDigits2(int userNumber, int res)
{
if ( userNumber == 0 )
{
return res;
}
return reverseDigits2(userNumber/10, 10*res + (userNumber%10));
}
int reverseDigits(int userNumber)
{
return reverseDigits2(userNumber, 0);
}

Related

C - Recursion instead of loops

I made a program that evaluates expressions, for example
Enter text: 97+74/51-98-11+68-34-2-22+73/40+81/15+100
output :
105.36
If any wrong data is given a user gets a response Incorrect input
I am wondering if I could replace all my for loops to recursion, but I don't know how could I achieve that. Could anybody help ?
Any assistance would be much appreciated.
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include<math.h>
int my_atoi(const char* tab, int from, int to)
{
int score = 0;
int minus = 0;
for (int i = from; i <= to; i++)
{
if (*(tab + i) == 10)
break;
if (*(tab + i) == 32)
break;
if (*(tab + i) == '-' && from == i)
{
minus = 1;
continue;
}
if (*(tab + i) == '+' && i == from)
{
continue;
}
if (*(tab + i) > '9' || *(tab + i) < '0')
break;
else if (*(tab + i) >= '0' && *(tab + i) <= '9')
{
score *= 10;
score += (*(tab + i) - '0');
}
}
if (minus == 1)
score *= -1;
return score;
}
int validate_expression(const char* expr)
{
if (!expr)return -1;
int lng = strlen(expr) - 1;
if (*(expr) > '9' || *(expr) < '0' || * (expr + lng) > '9' || *(expr + lng) < '0')return 0;
int flaga = 0; // flag
for (int i = 1; i < lng; i++) {
if (*(expr + i) <= '9' && *(expr + i) >= '0')
{
flaga = 0;
}
else if (*(expr + i) == '/' || *(expr + i) == '*' || *(expr + i) == '-' || *(expr + i) == '+')
{
if (flaga == 1)
return 0;
flaga = 1;
}
else
return 0;
}
return 1;
}
int calculate(const char* expr, float* result)
{
if (!expr || !result || !validate_expression(expr)) return 0;
if (strpbrk(expr, "i") != NULL) return 0;
int index = 0;
float score = 0;
char sign_memory = 'A';
int flaga = 0;
unsigned int i = 1;
for (; i <= strlen(expr); i++) {
if (*(expr + i) == '-' || *(expr + i) == '+' || *(expr + i) == '/' || *(expr + i) == '*' || *(expr + i) == '\0') {
score += (int)my_atoi(expr, index, i - 1);
index = i;
break;
}
}
for (; i <= strlen(expr); i++) {
if (*(expr + i) == '-' || *(expr + i) == '+' || *(expr + i) == '/' || *(expr + i) == '*' || i == strlen(expr)) {
flaga = 1;
if (sign_memory == '+')
score += (int)my_atoi(expr, index, i - 1);
else if (sign_memory == '-')
score -= (int)my_atoi(expr, index, i - 1);
else if (sign_memory == '/')
{
if (my_atoi(expr, index, i - 1) == 0)return 0;
score /= (int)my_atoi(expr, index, i - 1);
}
else if (sign_memory == '*')
score *= (int)my_atoi(expr, index, i - 1);
sign_memory = *(expr + i);
}
else if (*(expr + i) <= '9' && *(expr + i) >= '0' && flaga == 1) {
flaga = 0;
index = i;
}
}
*result = score;
return 1;
}
int main()
{
char tab[201];
float result, * pointer = &result;
printf("Enter text: ");
fgets(tab, sizeof(tab), stdin);
*(tab + strlen(tab) - 1) = '\0';
if (!validate_expression(tab))
{
printf("Incorrect input");
return 1;
}
else
{
if (calculate(tab, pointer))
printf("%.2f", *pointer);
else {
printf("Incorrect input");
return 1;
}
}
return 0;
}
I would make a function, which does the following:
Check if there is just one or more operators ("+", "-", "*", "/")
In case there is only one, perform the calculation.
In case there are two, perform a tail recursion, as proposed by Jonathan, something like:
calculate("97+74/51-98-11+68-34-2-22+73/40+81/15+100")
= calculate("97+74/51-98-11+68-34-2-22+73/40+81/15") + 100
= (calculate("97+74/51-98-11+68-34-2-22+73/40+81") / 15) + 100
= ((calculate("97+74/51-98-11+68-34-2-22+73/40") + 81) / 15) + 100
= (((calculate("97+74/51-98-11+68-34-2-22+73") / 40) + 81) / 15) + 100
= ((((calculate("97+74/51-98-11+68-34-2-22") + 73) / 40) + 81) / 15) + 100
= (((((calculate("97+74/51-98-11+68-34-2") - 22) + 73) / 40) + 81) / 15) + 100
= ((((((calculate("97+74/51-98-11+68-34") - 2) - 22) + 73) / 40) + 81) / 15) + 100
= (((((((calculate("97+74/51-98-11+68") - 34) - 2) - 22) + 73) / 40) + 81) / 15) + 100
= ((((((((calculate("97+74/51-98-11") + 68) - 34) - 2) - 22) + 73) / 40) + 81) / 15) + 100
= (((((((((calculate("97+74/51-98") - 11) + 68) - 34) - 2) - 22) + 73) / 40) + 81) / 15) + 100
= ((((((((((calculate("97+74/51") - 98) - 11) + 68) - 34) - 2) - 22) + 73) / 40) + 81) / 15) + 100
= (((((((((((calculate("97+74") / 51) - 98) - 11) + 68) - 34) - 2) - 22) + 73) / 40) + 81) / 15) + 100
= ((((((((((((97 + 74) / 51) - 98) - 11) + 68) - 34) - 2) - 22) + 73) / 40) + 81) / 15) + 100

C function doesn't return string, though it should

I'm super new in C, trying to solve CS50's credit problem here.
So I wrote a function, that should check some parameters, and return a string, which I use in the main function to print an answer.
#include <stdio.h>
#include <stdlib.h>
#include <cs50.h>
#include <math.h>
int lunh(long n);
char* check(long nu);
int main(void)
{
long number = get_long("Number: ");
printf("%s", check(number));
}
int lunh(long n)
{
int length, step_one, num;
long tens;
step_one = 0;
length = floor(log10(labs(n))) + 1;
for (int i = length, powering = 1; i > length / 2; i--)
{
tens = pow(10, powering);
num = ((n / tens) % 10) * 2;
if (floor(log10(abs(num))) + 1 > 1)
{
while (num)
{
step_one += num % 10;
num /= 10;
}
step_one += num;
powering += 2;
}
else
{
step_one += num;
powering += 2;
}
}
for (int i = length, powering = 0; i > length / 2; i--)
{
tens = pow(10, powering);
num = ((n / tens) % 10);
step_one += num;
powering += 2;
}
if (step_one % 10 == 0)
{
return 1;
}
else
{
return 0;
}
}
char* check(long nu)
{
int l, first_two_digits, first_one;
l = floor(log10(labs(nu))) + 1;
first_one = nu / 1000;
first_two_digits = nu / 100;
char* answer = NULL;
if (l == 15)
{
if (first_two_digits == 34 || first_two_digits == 37)
{
if (lunh(nu) == 1)
{
answer = "AMEX";
}
else
{
answer = "INVALID";
}
}
}
else if (l == 13 || first_one == 4)
{
if (lunh(nu) == 1)
{
answer = "VISA";
}
else
{
answer = "INVALID";
}
}
else if (l == 16)
{
if (first_two_digits == 51 || first_two_digits == 52 || first_two_digits == 53 || first_two_digits == 54 || first_two_digits == 55)
{
if (lunh(nu) == 1)
{
answer = "MASTERCARD";
}
else
{
answer = "INVALID";
}
}
}
else
{
answer = "INVALID";
}
printf("%s", answer);
return answer;
}
Input: 4003600000000014
Expected output: "VISA"
Current output: nothing, after inputting the number, the program stops.
At least one problem is here: else if (l == 13 || first_one == 4). From the spec:
Visa uses 13- and 16-digit numbers.
Visa numbers all start with 4
That if test will produce VISA if length is 13 or card starts with 4. The sample input is a 16 digit number.

CS50 filter: I'm getting a new error which I'm not familiar with

I've been working on the edge filter function for cs50 for a few hours now. It looks fine to me but I'm receiving a pretty scary looking error which I don't understand here is my code:
// Detect edges
void edges(int height, int width, RGBTRIPLE image[height][width])
{
RGBTRIPLE copy[height][width];
for (int h = 0; h < height; h++)
{
for (int w = 0; w < width; w++)
{
copy[h][w] = image[h][w];
}
}
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
float gxred = 0;
float gxgreen = 0;
float gxblue = 0;
float gyred = 0;
float gygreen = 0;
float gyblue = 0;
for (int r = -1; r < 2; r++)
{
for (int s = -1; s < 2; s++)
{
if ((y + r < height && y + r >= 0) && (x + s < width && x + s >= 0))
{
if (r == -1)
{
gxred = copy[y + r][x + s].rgbtRed * s;
gxgreen = copy[y + r][x + s].rgbtGreen * s;
gxblue = copy[y + r][x + s].rgbtBlue * s;
gyred = copy[x + s][y + r].rgbtRed * s;
gygreen = copy[x + s][y + r].rgbtGreen * s;
gyblue = copy[x + s][y + r].rgbtBlue * s;
}
if (r == 0)
{
gxred = copy[y + r][x + s].rgbtRed * (s * 2);
gxgreen = copy[y + r][x + s].rgbtGreen * (s * 2);
gxblue = copy[y + r][x + s].rgbtBlue * (s * 2);
gyred = copy[x + s][y + r].rgbtRed * (s * 2);
gygreen = copy[x + s][y + r].rgbtGreen * (s * 2);
gyblue = copy[x + s][y + r].rgbtBlue * (s * 2);
}
if (r == 1)
{
if (s * s == 1)
{
gxred = copy[y + r][x + s].rgbtRed * (s * s);
gxgreen = copy[y + r][x + s].rgbtGreen * (s * s);
gxblue = copy[y + r][x + s].rgbtBlue * (s * s);
gyred = copy[x + s][y + r].rgbtRed * (s * s);
gygreen = copy[x + s][y + r].rgbtGreen * (s * s);
gyblue = copy[x + s][y + r].rgbtBlue * (s * s);
}
else
{
gxred = copy[y + r][x + s].rgbtRed * (s + 1);
gxgreen = copy[y + r][x + s].rgbtGreen * (s + 1);
gxblue = copy[y + r][x + s].rgbtBlue * (s + 1);
gyred = copy[x + s][y + r].rgbtRed * (s + 1);
gygreen = copy[x + s][y + r].rgbtGreen * (s + 1);
gyblue = copy[x + s][y + r].rgbtBlue * (s + 1);
}
}
}
}
}
image[y][x].rgbtRed = round(sqrt((gxred * gxred) + (gyred * gyred)));
image[y][x].rgbtGreen = round(sqrt((gxgreen * gxgreen) + (gygreen * gygreen)));
image[y][x].rgbtBlue = round(sqrt((gxblue * gxblue) + (gyblue * gyblue)));
image[y][x].rgbtRed = image[y][x].rgbtRed % 256;
image[y][x].rgbtGreen = image[y][x].rgbtGreen % 256;
image[y][x].rgbtBlue = image[y][x].rgbtBlue % 256;
}
}
return;
}
And here is my error
helpers.c:169:37: runtime error: 261 is outside the range of representable values of type
'unsigned char'
UndefinedBehaviorSanitizer:DEADLYSIGNAL
==5405==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x7ffea18b01fa (pc
0x000000429bb3 bp 0x7ffea18af1a0 sp 0x7ffea17fe250 T5405)
==5405==The signal is caused by a READ memory access.
#0 0x429bb2 (/home/ubuntu/pset4/filter/filter+0x429bb2)
#1 0x42330e (/home/ubuntu/pset4/filter/filter+0x42330e)
#2 0x7f7c0b22eb96 (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#3 0x402e19 (/home/ubuntu/pset4/filter/filter+0x402e19)
UndefinedBehaviorSanitizer can not provide additional info.
==5405==ABORTING
This directs me to this line at the end:
image[y][x].rgbtGreen = round(sqrt((gxgreen * gxgreen) + (gygreen * gygreen)));
I'd be really grateful if someone could explain what this kind of error means. And also, any critique on my code would be much appreciated, I'm trying to get good at this.
RGB values can be any value between 0 and 255.
You are somehow assigning your RGB value in that line to 261 which is outside of the range.
I would print the value in the following code before assigning to rgb value.
round(sqrt((gxgreen * gxgreen) + (gygreen * gygreen)))
Then check why inside of round gives 261. Once you fix this you are good to go.

Create a particle circle

I'm creating a particles engine in C (with the CSFML library) where each particle has a position on {X,Y}, a life, and a movement vector in {X,Y}.
I'm actually creating X particles at the same position on my screen (ex: {100, 100}, and i wan't to make them moving to create a growing circle from the initial position.
What is the mathematical function that can help me to make this ?
#include <SFML/Graphics/Vertex.h>
#include <math.h>
#include "main.h"
int my_rand(int a, int b){
return rand()%(b-a) +a;
}
partBuffer *newPartBuffer(int size)
{
partBuffer *this;
const size_t size_m = (sizeof(partBuffer) + sizeof(sfVertex) * size * 4
+ sizeof(t_info) * size);
void *ptn = malloc(size_m);
if (ptn == NULL)
return (NULL);
memset(ptn, 0, size_m);
this = (partBuffer*)(ptn);
this->size = size;
this->vertex = (sfVertex*)(ptn + sizeof(partBuffer));
this->info = (t_info*)(this->vertex + (size * 4));
return (this);
}
void setPart(partBuffer *this, uint id, sfVector2f pos)
{
if (id >= this->size)
return ;
this->vertex[(id * 4) + 0].position = (sfVector2f){pos.x + 0, pos.y + 0};
this->vertex[(id * 4) + 1].position = (sfVector2f){pos.x + 5, pos.y + 0};
this->vertex[(id * 4) + 2].position = (sfVector2f){pos.x + 5, pos.y + 5};
this->vertex[(id * 4) + 3].position = (sfVector2f){pos.x + 0, pos.y + 5};
this->vertex[(id * 4) + 0].color = (sfColor){255, 255, 255};
this->vertex[(id * 4) + 1].color = (sfColor){255, 255, 255};
this->vertex[(id * 4) + 2].color = (sfColor){255, 255, 255};
this->vertex[(id * 4) + 3].color = (sfColor){255, 255, 255};
//this->info[id].speed = (sfVector2f){my_rand(-3, 3), my_rand(-3, 3)};
this->info[id].speed = (sfVector2f){0, 0};
this->info[id].life = 1.0;
}
static uint newPart(partBuffer *this)
{
for (uint id = this->size - 1; id != 0; id -= 1)
if (this->info[id].life <= 0)
return (id);
return ((uint)(-1));
}
void updatePartBuffer(partBuffer *this)
{
for (uint id = 0; id < this->size; id += 1) {
if (this->info[id].life > 0)
this->info[id].life -= 0.0;
if (this->info[id].life <= 0)
this->info[id].life = 0.0;
this->vertex[(id * 4) + 0].position.x += this->info[id].speed.x;
this->vertex[(id * 4) + 1].position.x += this->info[id].speed.x;
this->vertex[(id * 4) + 2].position.x += this->info[id].speed.x;
this->vertex[(id * 4) + 3].position.x += this->info[id].speed.x;
this->vertex[(id * 4) + 0].position.y += this->info[id].speed.y;
this->vertex[(id * 4) + 1].position.y += this->info[id].speed.y;
this->vertex[(id * 4) + 2].position.y += this->info[id].speed.y;
this->vertex[(id * 4) + 3].position.y += this->info[id].speed.y;
this->vertex[(id * 4) + 0].color.a = (sfUint8)(this->info[id].life * 255.);
this->vertex[(id * 4) + 1].color.a = (sfUint8)(this->info[id].life * 255.);
this->vertex[(id * 4) + 2].color.a = (sfUint8)(this->info[id].life * 255.);
this->vertex[(id * 4) + 3].color.a = (sfUint8)(this->info[id].life * 255.);
}
}
void drawPartBuffer(partBuffer *this, sfRenderWindow *window)
{
sfRenderWindow_drawPrimitives(window, this->vertex, this->size * 4,
sfQuads, NULL);
}
void set_circle(partBuffer *this, float points)
{
sfVector2f start = {0, -1};
sfVector2f adder = {1 / (points), 1 / (points)};
for (uint id = 0; id < points; id += 1) {
this->info[id].speed = (sfVector2f){start.x + adder.x * id, start.y + adder.y * id};
}
}
int game_loop(sfRenderWindow *window)
{
partBuffer *buffer = newPartBuffer(10000);
int points = 11;
sfClock *clock = sfClock_create();
sfVector2f position = {250, 250};
for (uint nb = 0; nb < points; nb += 1)
setPart(buffer, nb, position);
set_circle(buffer, points);
while (sfRenderWindow_isOpen(window)) {
if (sfTime_asMilliseconds(sfClock_getElapsedTime(clock)) >= 10) {
updatePartBuffer(buffer);
sfClock_restart(clock);
}
sfRenderWindow_clear(window, sfBlack);
drawPartBuffer(buffer, window);
sfRenderWindow_display(window);
}
}
int main(void)
{
sfRenderWindow *window = sfRenderWindow_create((sfVideoMode){500, 500, 32},
"Title", sfDefaultStyle, NULL);
sfRenderWindow_setFramerateLimit(window, 120);
game_loop(window);
return (0);
}

MQL4: Issue with finding low value

I am trying to get the highest and lowest value from last 20 bar. I have no issue to obtaining highest value, however my code doesn't seem to work properly in order to obtain the lowest value. Just wondering if there is any suggestion about it.
OnEveryNewBar1();
void OnEveryNewBar1()
{ PipValue = 1;
if ( NDigits == 3 || NDigits == 5 ) PipValue = 10;
if ( BarTime1 < Time[0] ) // we have a new bar opened
{ BarTime1 = Time[0]; // keep the new bar open time
TechnicalAnalysis_S();
TechnicalAnalysis_L();
}
}
void TechnicalAnalysis_S()
{
int m = 2;
int n = 3;
l = 1000;
while ( m <= 20 )
{
if ( 1 < 2 )
{ if ( ( Close[2] > Open[2] ) || ( Close[1] > Open[1] ) ) int i = 2;
while ( i > 0 )
{
if ( Low[i] < l ) l = Low[i];
i = i - 1;
}
print ( "Lowest" + l );
l = 1000;
}
m++;
n++;
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void TechnicalAnalysis_L()
{
int m = 2;
int n = 3;
while ( m <= 20 )
{
if ( 2 > 0 )
{
if ( ( Close[2] < Open[2] ) || ( Close[1] < Open[1] ) ) int i=2;
while ( i > 0 )
{
if ( High[i] > h ) h = High[i];
i = i - 1;
}
print ( "Highest" + h );
h = 0;
}
m++;
n++;
}
}
While there are some strange parts in the code, while some variables are missing their declaration, the language has built-in functions for this.
Solution:
double aLowestLOW_InTheLast20BARs,
aHighestHIGH_InTheLast20BARs;
// -----------------------------------------------------------------------------
aLowestLOW_InTheLast20BARs = Low[iLowest( _Symbol, // .self
PERIOD_CURRENT, // .self
MODE_LOW, // LOW
20, // Last 20 BARs
0 // from [0]
)
];
// -----------------------------------------------------------------------------
aHighestHIGH_InTheLast20BARs = High[iHighest( _Symbol, // .self
PERIOD_CURRENT, // .self
MODE_HIGH, // HIGH
20, // Last 20 BARs
0 // from [0]
)
];

Resources