Rounding off an integer to always end on 0 - c

I'm making a program to calculate the number of perfect squares between 1 and another number, and I want the counter to take only the first number of the integer, and put 0 on the rest, e.g: Result of the calculation is 31, I want to display 30, if it's 190, then display 100, and so on.
int number;
int i = 1;
int perfectCounter = 0;
printf("Enter a number: ");
scanf("%d", &number);
while (i <= number) {
float tempSquare = sqrt(i);
int integerPart = tempSquare;
if (tempSquare == integerPart)
perfectCounter++;
i++;
}
printf("%d", perfectCounter);
That's the code that I have right now, if I insert 1000, it will display 31, and I want it to display 30, I can't think a solution for this.

Divide the number by the highest power of 10 below the number. Do this using integer arithmetic, so it gets the integer part of the division. Then multiply by the power of 10.
#include <math.h>
int powerOf10 = pow(10, (int)log10(perfectCounter));
int roundedCounter = (perfectCounter/powerOf10)*powerOf10;
printf("%d", roundedCounter);

You can use a function like this one to round your numbers. Basically what it does is it "chips away" one digit at a time until we are left with only one digit and then adds appropriate number of zeros to it:
int round(int _in){
int numDigits = 0;
while(_in > 9){
++numDigits;
_in /= 10;
}
int res = _in; // whatever is left would be the left-most digit
for(int i = 0; i < numDigits; ++i){
res *= 10;
}
return res;
}

Here's a simple solution with no math:
void print_rounded(int i) {
unsigned u = i;
if (i < 0) { putchar('-'); u = -i; }
char buf[2];
int n = snprintf(buf, 2, "%u", u);
for (putchar(buf[0]); --n; putchar('0')) {}
}
(In other words, print the first digit, and then print enough 0's to make up the length of the original number.)

Related

C program to find integer closest to 10

I am writing a program that will take any number of integers. The program will end when the terminal 0 has been entered. It will then output the number closest to 10 (except for the terminal character). If there are several numbers closest to 10 then it should output the last number entered.
My current code does read the numbers from the input stream, but I don't know how to implement the logic so that the program will give me the number that is closest to 10.
I know, that I need to keep track of the minimum somehow in order to update the final result.
#include <stdio.h>
int main() {
int n = 1;
int number = 1;
int numberArray[n];
int resultArray[n];
int min;
int absMin;
int result;
int finalResult;
while (number != 0) {
scanf("%d", &number);
numberArray[n] = number;
n++;
}
for (int i = 0; i < n; i++) {
min = 10 - numberArray[i];
if (min < 0) {
absMin = -min;
}
else {
absMin = min;
}
resultArray[i] = absMin;
result = resultArray[0];
if (resultArray[i] < result) {
finalResult = resultArray[i];
}
}
printf("%d\n", finalResult);
return 0;
}
here's a simple code I wrote
One thing I must say is you can't simply declare an array with unknown size and that's what you have done. Even if the no. of elements can vary, you either take input the number of elements from the user OR (like below) create an array of 100 elements or something else according to your need.
#include <stdio.h>
#define _CRT_NO_WARNINGS
int main() {
int n = 0;
int number = 1;
int numberArray[100];
int resultArray[100];
int minNumber;
int *min;
do {
scanf("%d", &number);
numberArray[n] = number;
n++;
}
while (number != 0);
resultArray[0] = 0;
min = &resultArray[0];
minNumber = numberArray[0];
for (int i = 0; i < n-1; i++) {
if(numberArray[i]>=10){
resultArray[i] = numberArray[i] - 10;
}
if(numberArray[i]<10){
resultArray[i] = 10 - numberArray[i];
}
if(resultArray[i] <= *min){
min = &resultArray[i];
minNumber = numberArray[i];
}
}
printf("\n%d",minNumber);
return 0;
}
I have improved your script and fixed a few issues:
#include <stdio.h>
#include <math.h>
#include <limits.h>
int main()
{
int n;
int number;
int numberArray[n];
while (scanf("%d", &number) && number != 0) {
numberArray[n++] = number;
}
int currentNumber;
int distance;
int result;
int resultIndex;
int min = INT_MAX; // +2147483647
for (int i = 0; i < n; i++) {
currentNumber = numberArray[i];
distance = fabs(10 - currentNumber);
printf("i: %d, number: %d, distance: %d\n", i, currentNumber, distance);
// the operator: '<=' will make sure that it will update even if we already have 10 as result
if (distance <= min) {
min = distance;
result = currentNumber;
resultIndex = i;
}
}
printf("The number that is closest to 10 is: %d. It is the digit nr: %d digit read from the input stream.\n", result, resultIndex + 1);
return 0;
}
Reading from the input stream:
We can use scanf inside the while loop to make it more compact. Also, it will loop one time fewer because we don't start with number = 1 which is just a placeholder - this is not the input - we don't want to loop over that step.
I used the shorthand notation n++ it is the post-increment-operator. The operator will increase the variable by one, once the statement is executed (numberArray entry will be set to number, n will be increased afterwards). It does the same, in this context, as writing n++ on a new line.
Variables:
We don't need that many. The interesting numbers are the result and the current minimum. Of course, we need an array with the inputs as well. That is pretty much all we need - the rest are just helper variables.
Iteration over the input stream:
To get the result, we can calculate the absolute distance from 10 for each entry. We then check if the distance is less than the current minimum. If it is smaller (closer to 10), then we will update the minimum, the distance will be the new minimum and I have added the resultIndex as well (to see which input is the best). The operator <= will make sure to pick the latter one if we have more than one number that has the same distance.
I have started with the minimum at the upper bound of the integer range. So this is the furthest the number can be away from the result (we only look at the absolute number value anyway so signed number don't matter).
That's pretty much it.

Finding numbers with unique digits in C

I have to write a program that finds every number (except 0) which can be factored by numbers from 2-9.
For example first such a number would be number 2520 as it can be divided by every single number from 2 to 9.
It also has to be a number that contains only 1 type of digit of its own (no multiple digits in a number). So for example 2520 will not meet this requirement since there are two same digits (2). The example of a number that meets both requirements is number 7560. That is the point I don't how to do it. I was thinking about converting value in an array to string, and then putting this string in another array so every digit would be represented by one array entry.
#include <stdio.h>
#include <math.h>
int main() {
int i, n, x, flag, y = 0;
scanf("%d", &n);
double z = pow(10, n) - 1;
int array[(int)z];
for (i = 0; i <= z; i++) {
flag = 0;
array[i] = i;
if (i > 0) {
for (x = 2; x <= 9; x++) {
if (array[i] % x != 0) {
flag = 1;
}
}
if (flag == 0) {
y = 1;
printf("%d\n", array[i]);
}
}
}
if (y == 0) {
printf("not exist");
}
return 0;
}
This should give you a base:
#include <stdio.h>
#include <string.h>
int main()
{
char snumber[20];
int number = 11235;
printf("Number = %d\n\n", number);
sprintf(snumber, "%d", number);
int histogram[10] = { 0 };
int len = strlen(snumber);
for (int i = 0; i < len; i++)
{
histogram[snumber[i] - '0']++;
}
for (int i = 0; i < 10; i++)
{
if (histogram[i] != 0)
printf("%d occurs %d times\n", i, histogram[i]);
}
}
Output:
Number = 11235
1 occurs 2 times
2 occurs 1 times
3 occurs 1 times
5 occurs 1 times
That code is a mess. Let's bin it.
Theorem: Any number that divides all numbers in the range 2 to 9 is a
multiple of 2520.
Therefore your algorithm takes the form
for (long i = 2520; i <= 9876543210 /*Beyond this there must be a duplicate*/; i += 2520){
// ToDo - reject if `i` contains one or more of the same digit.
}
For the ToDo part, see How to write a code to detect duplicate digits of any given number in C++?. Granted, it's C++, but the accepted answer ports verbatim.
If i understand correctly, your problem is that you need to identify whether a number is consisted of multiple digits.
Following your proposed approach, to convert the number into a string and use an array to represent digits, i can suggest the following solution for a function that implements it. The main function is used to test the has_repeated_digits function. It just shows a way to do it.
You can alter it and use it in your code.
#include <stdio.h>
#define MAX_DIGITS_IN_NUM 20
//returns 1 when there are repeated digits, 0 otherwise
int has_repeated_digits(int num){
// in array, array[0] represents how many times the '0' is found
// array[1], how many times '1' is found etc...
int array[10] = {0,0,0,0,0,0,0,0,0,0};
char num_string[MAX_DIGITS_IN_NUM];
//converts the number to string and stores it in num_string
sprintf(num_string, "%d", num);
int i = 0;
while (num_string[i] != '\0'){
//if a digit is found more than one time, return 1.
if (++array[num_string[i] - '0'] >= 2){
return 1; //found repeated digit
}
i++;
}
return 0; //no repeated digits found
}
// test tha function
int main()
{
int x=0;
while (scanf("%d", &x) != EOF){
if (has_repeated_digits(x))
printf("repeated digits found!\n");
else
printf("no repeated digits\n");
}
return 0;
}
You can simplify your problem from these remarks:
the least common multiple of 2, 3, 4, 5, 6, 7, 8 and 9 is 2520.
numbers larger than 9876543210 must have at least twice the same digit in their base 10 representation.
checking for duplicate digits can be done by counting the remainders of successive divisions by 10.
A simple approach is therefore to enumerate multiples of 2520 up to 9876543210 and select the numbers that have no duplicate digits.
Type unsigned long long is guaranteed to be large enough to represent all values to enumerate, but neither int nor long are.
Here is the code:
#include <stdio.h>
int main(void) {
unsigned long long i, n;
for (n = 2520; n <= 9876543210; n += 2520) {
int digits[10] = { 0 };
for (i = n; i != 0; i /= 10) {
if (digits[i % 10]++)
break;
}
if (i == 0)
printf("%llu\n", n);
}
return 0;
}
This program produces 13818 numbers in 0.076 seconds. The first one is 7560 and the last one is 9876351240.
The number 0 technically does match your constraints: it is evenly divisible by all non zero integers and it has no duplicate digits. But you excluded it explicitly.

Why is my to_base_n Program not working?

I need to write a C program which will read a number (in base 10) from user input and output it in any base which is a power of 2. The calculations have to be performed in one function, to_base_n, which takes the parameters num and base and prints the number in the respective base. As a validation check, the program also checks if the base is a power of two with the isPowerofTwo function.
The way the conversion is carried out is by means of long division which carries out the logic in the pseudocode below:
void to_base_n(int x, int n){
int r, i = 0
int digits[16]
while (x ≠ 0){
r = x mod n
x = x / n
digits[i] = r
i++
}
for (i = 0, i < 15, i++)
print digits[i]
}
Which I believe is arithmetically sound. But when I try to, for example, convert 82000 to base 4, I get the following output:
The large digits appearing are even bigger than num itself, so I figured the modulus cannot be entering the array properly (because ∀{x,n}; x mod n < x). I can't seem to find what's wrong with it. The full code is listed below.
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
bool isPowerofTwo(int);
void to_base_n(int, int);
int main(){
//Variables
int num, base;
//Prompt
printf("Please enter a number in base 10: ");
scanf("%d", &num);
printf("Please enter a base (2^n) to convert it to: ");
scanf("%d", &base);
//Precaution
while(!isPowerofTwo(base)){
printf("That number is not a power of 2. Please try again: ");;
scanf("%d", &base);
}
if(isPowerofTwo(base)){
//Output
printf("The number %d (base 10) is equivalent to ", num);
to_base_n(num, base);
printf(" (base %d).", base);
}
//Return Statement
return 0;
}
//Checks if Base is a Power of Two
bool isPowerofTwo(int base){
while((base % 2 == 0) && base > 1){
base = base / 2;
if(base == 1){
return true;
break;
}
}
return false;
}
//to_base_n
void to_base_n(int x, int n){
int r, i = 0;
int digits[16];
while(x != 0){
r = x % n;
x = x / n;
digits[i] = r;
i++;
}
for(i = 0; i < 15; i++)
printf("%d|",digits[i]);
}
Can anyone help explain what's wrong with it?
The number 82000 in base 4 would be:
110001100
Which is exacly what you get. Your mistake is that:
They are printed backwards.
You are printing more digits than you should, so you print garbage.
You ignore the number of digits extracted with your pseudo code, so you print uninitialised elements of the array.
for (i = 0, i < 15, i++)
print digits[i]
And they are printed in reverse order. I suggest changing it to this
for (i = i - 1, i >= 0, i--)
print digits[i]
and as C code in your function
for(i = i - 1; i >= 0; i--)
printf("%d|",digits[i]);

Recursion, possible error in algo

i am doing one of the simple programin C, sum of digits of 5 digit number.Though i had done it using a simple function but i need to do it with recursion also.I had read many solution on net regarding this problem using recursion and had implemented one of mine.But that is giving error and i cant figure out what mesh i am doing in my algo.
#include<stdio.h>
int sum5(int x); //function for sum of digits of 5 digit number
int main()
{
int x;
int result;
printf("Enter a 5 digit number : ");
scanf("%d",&x);
printf("Number entered by you is %d",x);
result = sum5(x);
printf("Sum of digits of 5 digit number is = %d",&result);
return 0;
}
int sum5(int x)
{
int r;
int sum=0;
if(x!=0){
r=x%10;
sum=sum+r;
x=x-r; //doing this so that 0 come in the last and on diving it by 10, one digit will be removed.
sum5(x/10);
}
return sum;
}
but after its execution i am getting wrong result.It is dumping some anonymous value on the output.
Also, your sum5 function is incorrect. You have to add the value of sum5 to the sum variable of the caller function.
int sum5(int x)
{
int r;
int sum = 0;
if (x != 0) {
r = x % 10;
sum = r;
//x = x - r; - this isn't required. integer division will floor x
sum += sum5(x / 10);
}
return sum;
}
This is incorrect as it is printing the address of result and not its value:
printf("Sum of digits of 5 digit number is = %d",&result);
Change to:
printf("Sum of digits of 5 digit number is = %d", result);
Always check the result of scanf() to ensure a valid value was read:
/* Returns number of assignments made. */
if (scanf("%d", &x) == 1 && x > 9999 && x < 100000)
{
}
Plus the error in the implementation of sum5() as pointed out by Osiris
.

C: how to break apart a multi digit number into separate variables?

Say I have a multi-digit integer in C. I want to break it up into single-digit integers.
123 would turn into 1, 2, and 3.
How can I do this, especially if I don't know how many digits the integer has?
int value = 123;
while (value > 0) {
int digit = value % 10;
// do something with digit
value /= 10;
}
First, count the digits:
unsigned int count(unsigned int i) {
unsigned int ret=1;
while (i/=10) ret++;
return ret;
}
Then, you can store them in an array:
unsigned int num=123; //for example
unsigned int dig=count(num);
char arr[dig];
while (dig--) {
arr[dig]=num%10;
num/=10;
}
As a hint, getting the nth digit in the number is pretty easy; divide by 10 n times, then mod 10, or in C:
int nthdig(int n, int k){
while(n--)
k/=10;
return k%10;
}
The last digits of 123 is 123 % 10.
You can drop the last digit of 123 by doing 123/10 -- using integer division this will give you 12.
To answer your question about "how do I know how many digits you have" --
try doing it as described above and you will see how to know when to stop.
I think below piece of code will help....
temp = num;
while(temp)
{
temp=temp/10;
factor = factor*10;
}
printf("\n%d\n", factor);
printf("Each digits of given number are:\n");
while(factor>1)
{
factor = factor/10;
printf("%d\t",num/factor);
i++;
num = num % factor;
}
//Based on Tony's answer
#include <stdio.h>
int nthdig(int n, int k){
while(n--)
k/=10;
return k%10;
}
int main() {
int numberToSplit = 987;
printf("Hundreds = %i\n",nthdig(2, numberToSplit));
printf("Tens = %i\n",nthdig(1, numberToSplit));
printf("Units = %i\n",nthdig(0, numberToSplit));
}
This results in the following printout:
Hundreds = 9
Tens = 8
Units = 7
I made this based on the code from #asaelr:
typedef struct digitsArrayPlusNumber {
uint32_t *baseAddress;
uint32_t number;
} digitsArrayPlusNumber;
digitsArrayPlusNumber *splitDigits (uint32_t inValue) {
// based on code from asaelr#stackoverflow.com
uint32_t inputValue = inValue;
//Count digits
uint32_t theCount = 1;
while (inputValue /= 10)
theCount++;
// put in array
uint32_t *arr = malloc(sizeof(uint32_t) * theCount);
uint32_t dig = theCount;
while (dig--) {
arr[dig]=inValue % 10;
inValue /= 10;
// printf ("%d\n", arr[dig]);
}
digitsArrayPlusNumber *dandn = malloc (sizeof(digitsArrayPlusNumber));
dandn->baseAddress = arr;
dandn->number = theCount;
return dandn;
}
int main(int argc, const char * argv[]) {
for (int d = 0; d < splitDigits(12345678)->number; d++)
printf ("%u\n", (splitDigits(12345678)->baseAddress)[d]);
}
It works quite well, thanks!
You can use %10, which means the remainder if the number after you divided it. So 123 % 10 is 3, because the remainder is 3, substract the 3 from 123, then it is 120, then divide 120 with 10 which is 12. And do the same process.
we can use this program as a function with 3 arguments.Here in "while(a++<2)", 2 is the number of digits you need(can give as one argument)replace 2 with no of digits you need. Here we can use "z/=pow(10,6)" if we don't need last certain digits ,replace 6 by the no of digits you don't need(can give as another argument),and the third argument is the number you need to break.
int main(){
long signed c=0,z,a=0,b=1,d=1;
scanf("%ld",&z);
while(a++<2){
if(d++==1)
z/=pow(10,6);
c+=(z%10)*b;
z/=10;
b*=10;}
return c;}
You can divide and conquer but you have rewrite all of arithmetic libraries. I suggest using a multi-precision library https://gmplib.org But of course it is good practice

Resources