How can I concatenate an integer with desired times in C? - c

I want to write a function like this:
int number_maker(int n, int k)
{
if(k==1)
return n;
else
{
int x = 10;
while(n >= x)
x *= 10;
return (n*x) + number_maker(n,k-1) ;
}
}
For an example, let's say my number is 350. I want to make it based on
a repeated parameter. I can make it 350350 but when it comes to more repetitions like 3 or 4 times, it goes wrong.
I can't use standard C functions.

Your program is trying to store a number greater than INT_MAX in an int, which results in an overflow during conversion. Even if you modify your function to have a size_t return type, that will only get you so far. The only way to be sure that your program produces accurate output is to store the concatenated integer as a char* and return that, instead.

While it is possible to repeat any three digit repetition in a 32-bit int, three times, it is not possible to fit four repetitions as only all 9 digit decimal integers can be represented.
Your problem with three repetitions is because on each recursion x is always 1000 (for a three digit n), whereas you actually need it to be 1000000 on the second recursion. Solving that is somewhat cumbersome, but you need to pass x into the number_maker thus:
int number_maker(int n, int k, int x) // <<< additional parameter
{
if(k==1)
return n;
else
{
int xx = x ; // <<< added
while(n * xx >= x) // <<< modified
x *= 10;
return (n*x) + number_maker(n,k-1, x) ;
}
}
Then a call such as:
printf("%d", number_maker( 350, 3, 1 ) );
will work. It is cumbersome because you have to pass an initial x value, and that can only be 1. In C++ you could use an default argument to hide that.
It will not work however for 4 repetitions or a three digit decimal integer.
That said:
printf("%d", number_maker( 1, 9, 1 ) );
printf("%d", number_maker( 9, 9, 1 ) );
work ok. You can get away with 10 repetitions only for n==1.
printf("%d", number_maker( 1, 10, 1 ) );
Essentially it works for all 9 digit results and (less usefully) some 10 digit results.
Using unsigned integers would increase the number of 10 digit results that could be represented, but that is not particularly useful perhaps.

Related

How to compute the digits of an irrational number one by one?

I want to read digit by digit the decimals of the sqrt of 5 in C.
The square root of 5 is 2,23606797749979..., so this'd be the expected output:
2
3
6
0
6
7
9
7
7
...
I've found the following code:
#include<stdio.h>
void main()
{
int number;
float temp, sqrt;
printf("Provide the number: \n");
scanf("%d", &number);
// store the half of the given number e.g from 256 => 128
sqrt = number / 2;
temp = 0;
// Iterate until sqrt is different of temp, that is updated on the loop
while(sqrt != temp){
// initially 0, is updated with the initial value of 128
// (on second iteration = 65)
// and so on
temp = sqrt;
// Then, replace values (256 / 128 + 128 ) / 2 = 65
// (on second iteration 34.46923076923077)
// and so on
sqrt = ( number/temp + temp) / 2;
}
printf("The square root of '%d' is '%f'", number, sqrt);
}
But this approach stores the result in a float variable, and I don't want to depend on the limits of the float types, as I would like to extract like 10,000 digits, for instance. I also tried to use the native sqrt() function and casting it to string number using this method, but I faced the same issue.
What you've asked about is a very hard problem, and whether it's even possible to do "one by one" (i.e. without working space requirement that scales with how far out you want to go) depends on both the particular irrational number and the base you want it represented in. For example, in 1995 when a formula for pi was discovered that allows computing the nth binary digit in O(1) space, this was a really big deal. It was not something people expected to be possible.
If you're willing to accept O(n) space, then some cases like the one you mentioned are fairly easy. For example, if you have the first n digits of the square root of a number as a decimal string, you can simply try appending each digit 0 to 9, then squaring the string with long multiplication (same as you learned in grade school), and choosing the last one that doesn't overshoot. Of course this is very slow, but it's simple. The easy way to make it a lot faster (but still asymptotically just as bad) is using an arbitrary-precision math library in place of strings. Doing significantly better requires more advanced approaches and in general may not be possible.
As already noted, you need to change the algorithm into a digit-by-digit one (there are some examples in the Wikipedia page about the methods of computing of the square roots) and use an arbitrary precision arithmetic library to perform the calculations (for instance, GMP).
In the following snippet I implemented the before mentioned algorithm, using GMP (but not the square root function that the library provides). Instead of calculating one decimal digit at a time, this implementation uses a larger base, the greatest multiple of 10 that fits inside an unsigned long, so that it can produce 9 or 18 decimal digits at every iteration.
It also uses an adapted Newton method to find the actual "digit".
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <gmp.h>
unsigned long max_ul(unsigned long a, unsigned long b)
{
return a < b ? b : a;
}
int main(int argc, char *argv[])
{
// The GMP functions accept 'unsigned long int' values as parameters.
// The algorithm implemented here can work with bases other than 10,
// so that it can evaluate more than one decimal digit at a time.
const unsigned long base = sizeof(unsigned long) > 4
? 1000000000000000000
: 1000000000;
const unsigned long decimals_per_digit = sizeof(unsigned long) > 4 ? 18 : 9;
// Extract the number to be square rooted and the desired number of decimal
// digits from the command line arguments. Fallback to 0 in case of errors.
const unsigned long number = argc > 1 ? atoi(argv[1]) : 0;
const unsigned long n_digits = argc > 2 ? atoi(argv[2]) : 0;
// All the variables used by GMP need to be properly initialized before use.
// 'c' is basically the remainder, initially set to the original number
mpz_t c;
mpz_init_set_ui(c, number);
// At every iteration, the algorithm "move to the left" by two "digits"
// the reminder, so it multplies it by base^2.
mpz_t base_squared;
mpz_init_set_ui(base_squared, base);
mpz_mul(base_squared, base_squared, base_squared);
// 'p' stores the digits of the root found so far. The others are helper variables
mpz_t p;
mpz_init_set_ui(p, 0UL);
mpz_t y;
mpz_init(y);
mpz_t yy;
mpz_init(yy);
mpz_t dy;
mpz_init(dy);
mpz_t dx;
mpz_init(dx);
mpz_t pp;
mpz_init(pp);
// Timing, for testing porpuses
clock_t start = clock(), diff;
unsigned long x_max = number;
// Each "digit" correspond to some decimal digits
for (unsigned long i = 0,
last = (n_digits + decimals_per_digit) / decimals_per_digit + 1UL;
i < last; ++i)
{
// Find the greatest x such that: x * (2 * base * p + x) <= c
// where x is in [0, base), using a specialized Newton method
// pp = 2 * base * p
mpz_mul_ui(pp, p, 2UL * base);
unsigned long x = x_max;
for (;;)
{
// y = x * (pp + x)
mpz_add_ui(yy, pp, x);
mpz_mul_ui(y, yy, x);
// dy = y - c
mpz_sub(dy, y, c);
// If y <= c we have found the correct x
if ( mpz_sgn(dy) <= 0 )
break;
// Newton's step: dx = dy/y' where y' = 2 * x + pp
mpz_add_ui(yy, yy, x);
mpz_tdiv_q(dx, dy, yy);
// Update x even if dx == 0 (last iteration)
x -= max_ul(mpz_get_si(dx), 1);
}
x_max = base - 1;
// The actual format of the printed "digits" is up to you
if (i % 4 == 0)
{
if (i == 0)
printf("%lu.", x);
putchar('\n');
}
else
printf("%018lu", x);
// p = base * p + x
mpz_mul_ui(p, p, base);
mpz_add_ui(p, p, x);
// c = (c - y) * base^2
mpz_sub(c, c, y);
mpz_mul(c, c, base_squared);
}
diff = clock() - start;
long int msec = diff * 1000L / CLOCKS_PER_SEC;
printf("\n\nTime taken: %ld.%03ld s\n", msec / 1000, msec % 1000);
// Final cleanup
mpz_clear(c);
mpz_clear(base_squared);
mpz_clear(p);
mpz_clear(pp);
mpz_clear(dx);
mpz_clear(y);
mpz_clear(dy);
mpz_clear(yy);
}
You can see the outputted digits here.
Your title says:
How to compute the digits of an irrational number one by one?
Irrational numbers are not limited to most square roots. They also include numbers of the form log(x), exp(z), sin(y), etc. (transcendental numbers). However, there are some important factors that determine whether or how fast you can compute a given irrational number's digits one by one (that is, from left to right).
Not all irrational numbers are computable; that is, no one has found a way to approximate them to any desired length (whether by a closed form expression, a series, or otherwise).
There are many ways numbers can be expressed, such as by their binary or decimal expansions, as continued fractions, as series, etc. And there are different algorithms to compute a given number's digits depending on the representation.
Some formulas compute a given number's digits in a particular base (such as base 2), not in an arbitrary base.
For example, besides the first formula to extract the digits of π without computing the previous digits, there are other formulas of this type (known as BBP-type formulas) that extract the digits of certain irrational numbers. However, these formulas only work for a particular base, not all BBP-type formulas have a formal proof, and most importantly, not all irrational numbers have a BBP-type formula (essentially, only certain log and arctan constants do, not numbers of the form exp(x) or sqrt(x)).
On the other hand, if you can express an irrational number as a continued fraction (which all real numbers have), you can extract its digits from left to right, and in any base desired, using a specific algorithm. What is more, this algorithm works for any real number constant, including square roots, exponentials (e and exp(x)), logarithms, etc., as long as you know how to express it as a continued fraction. For an implementation see "Digits of pi and Python generators". See also Code to Generate e one Digit at a Time.

No output for long long int variables

Here is a code snippet:
unsigned int m,n,a;
long long int c,p=0,q=0;
scanf("%u%u%u",&m,&n,&a);
while(m>0){
m-=a;
p++;
}
while(n>0){
n-=a;
q++;
}
c=p*q;
printf("%lld",c);
The above code does not work for any input. That is, it seems like it has crashed,though I could not understand where I'm mistaken. I guess the part with %lld in the printf has problems. But Ido not know how to fix it. I'm using code blocks.
Some expected outputs for corresponding inputs are as follows:
Input: 6 6 4
Output: 4
Input: 1000000000 1000000000 1
Output: 1000000000000000000(10^18).
APPEND:
So, I'm giving the link of the main problem below. The logic of my code seemed correct to me.
https://codeforces.com/contest/1/problem/A
As it's been pointed out in comments/answers the problem is that m and n is unsigned so your loops can only stop if m and n are a multiple of a.
If you look at the input 6 6 4 (i.e. m=6 and a=4), you can see that m first will change like m = 6 - 4 which leads to m being 2. So in the next loop m will change like m = 2 - 4 which should be -2 but since m is unsigned it will wrap to a very high positive number (i.e. UINT_MAX-1) and the loop will continue. That's not what you want.
To fix it I'll suggest you drop the while loops and simply do:
unsigned int m,n,a;
long long unsigned int c,p=0,q=0;
scanf("%u%u%u",&m,&n,&a);
p = (m + a - 1)/a; // Replaces first while
q = (n + a - 1)/a; // Replaces second while
c=p*q;
printf("%lld",c);
One problem with this solution is that the sum (m + a - 1) may overflow (i.e. be greater than UINT_MAX) and therefore give wrong results. You can fix that by adding an overflow check before doing the sum.
Another way to protect against overflow could be:
p = 1; // Start with p=1 to handle m <= a
if (m > a)
{
m -= a; // Compensate for the p = 1 and at the same time
// ensure that overflow won't happen in the next line
p += (m + a - 1)/a;
}
This code can then be reduced to:
p = 1;
if (m > a)
{
p += (m - 1)/a;
}
while(m>0){
m-=a;
p++;
}
will run until m is equal to 0, since it cannot be negative because it is unsigned. So if m is 4 and a is 6, then m will underflow and get the maximum value that m can hold minus 2. You should change the input variables to signed.
4386427 shows how you can use math to remove the loops completely, but for the more general case, you can do like this:
while(m > a) {
m-=a;
p++;
}
// The above loop will run one iteration less
m-=a;
p++;
Of course, you need to do the same thing for the second loop.
Another thing, check return value of scanf:
if(scanf("%u%u%u",&m,&n,&a) != 3) {
/* Handle error */
}
Using an unsigned type isn't always the best choice to represent positive values, expecially when its modular behavior is not needed (and maybe forgotten, which leads to "unexpected" bugs). OP's use case requires an integral type capable of store a value of maximum 109, which is inside the range of a 32-bit signed integer (a long int to be sure).
As 4386427's answer shows, the while loops in OP's code may (and should) be avoided anyways, unless a "brute force" solution is somehow required (which is unlikely the case, given the origin of the question).
I'd use a function, though:
#include <stdio.h>
// Given 1 <= x, a <= 10^9
long long int min_n_of_tiles_to_pave_an_edge(long int x, long int a)
{
if ( x > a ) {
// Note that the calculation is performed with 'long' values and only after
// the result is casted to 'long long', when it is returned
return 1L + (x - 1L) / a;
}
else {
return 1LL;
}
}
int main(void)
{
// Given a maximum value of 10^9, a 32-bit int would be enough.
// A 'long int' (or 'long') is guaranteed to be capable of containing at
// least the [−2,147,483,647, +2,147,483,647] range.
long int m, n, a;
while ( scanf("%ld%ld%ld", &m, &n, &a) == 3 )
{
// The product of two long ints may be too big to fit inside a long.
// To be sure, performe the multiplication using a 'long long' type.
// Note that the factors are stored in the bigger type, not only the
// result.
long long int c = min_n_of_tiles_to_pave_an_edge(m, a)
* min_n_of_tiles_to_pave_an_edge(n, a);
printf("%lld\n",c);
}
}

Why doesn't this factorial compute correctly?

I am trying to learn some C programming, and to test my basic skills, I am making a simple program that computes factorials. However, instead of giving the correct answer of 120 for the factorial of 5, it gives -1899959296. What's wrong? Here's my code below:
#include <stdio.h>
int factorial(int x)
{
int i;
for(i=1; i < x; i++)
x *= i;
return x;
}
int main()
{
int a = 5, b;
b = factorial(a);
printf("The factorial of %d is %d \n", a, b);
return 0;
}
Thanks in advance!
Your problem is that the function factorial() is continually modifying x. For any of x which is initially 3 or more, x will keep increasing, so the loop will keep running.
Consider if you call fact(3).
The function is called with x = 3. First iteration of the loop with i = 1 will multiply x by 1. So x will still have the value of 3. i i will be incremented to 2, which is less than 3, so the next iteration starts.
The second iteration of the loop will multiply x by 2, giving the result of 6. i is incremented to 3, which is less than 6, so the next iteration starts.
The third iteration will multiply x by 3, giving the result of 18. i is incremented to 4, which is less than 18, so the next iteration starts.
Notice the pattern in the above ..... the end condition is i < x. i is incremented in each iteration. x is multiplied by i. This means that x increases substantially faster than i does .... which means i < x is always true.
Well almost ..... eventually the logic breaks down.
Eventually x will overflow - the result of multiplying it by i will produce a result that exceeds what can be stored in an int. The result of overflowing an int is undefined ..... anything can happen at that point.
Compare the description above with what YOU would do if asked to compute the factorial of 3. Would you do similar steps? Probably not.
int factorial(int x)
{
int i;
int count =x;
for(i=1; i < count ; i++)
x *= i;
return x;
}
Modify like this. your issue is with the loop count.. Since value of x is changing the loop may become infinite..
C) You're using x as an upperbound for your for loop i < x
B) You're also increasing x nearly exponentially on every loop x *= i, your loop won't work.
You might have noticed that you get a negative number back. The reason the loop exits at all is that you've chosen to type x as a 32 bit signed integer (the default int)- The processor works in binary: so once you go higher than is actually possible with just 32 bits, it still tries to do math but it loses data and loops back around to negative numbers. So once x loops back around and becomes negative, then i > x and the loop exits.
Here: http://tpcg.io/8sX5ls
The error is in the for, the factorial of a number is n * n-1 * ... * n-(n-1), so to solve this, just start the index in x - 1 and decrement it until it turns 1, sorry for my bad English, I hope you understood what I said.
here is the answer:
for ( i = x - 1; i > 1; --i )
x *= i;
Just to explain why the negative number, first we must understand what happens in the for which it was declared.
for(i=1; i < x; i++)
x *= i;
As we can see the condition for it to continue in the loop is i < x, but within it is assigned to x the value of x * i (x * = i or x = x * i), so x has no constant value and is always increasing, the i increases at a velocity smaller than that of x because the i is always added to 1 (i ++, i + = 1 or i = i + 1), which causes the x to be unreachable , then the for will be in an infinite loop.
But every type has its range, and int is 4 bytes, therefore 32 bit, what happens is that there comes a time when x exceeds this range having the famous integer overflow, this is why its value is negative, then the condition of the for becomes false and then the for stop.
We have to remember that a number is represented in memory in binary form, and the last binary number is what represents whether the number is positive or negative, 0 is positive, 1 is negative, when integer overflow happens the last number changes to 1 , making it so negative.
To better understand this here are some links that can help:
https://en.wikipedia.org/wiki/Two%27s_complement
https://en.wikipedia.org/wiki/Integer_overflow.

How do I populate an array with the digits of a given integer in C? [duplicate]

This question already has answers here:
convert an integer number into an array
(8 answers)
Closed 7 years ago.
So lets say you have an integer in your code declared
int my_num = 967892;
and you have an array
int a[6];
How would you put that integer into the array so it looks like this?
{ 9, 6, 7, 8, 9, 2 }
Perhaps like this:
const unsigned char digits[] = { 9, 6, 7, 8, 9, 2 };
but there are many things that are unclear with your question, of course.
If you want to do this at runtime, as your comment now makes me believe, you need more code of course. Also, it will be tricky to make the array "fit" the number exactly, since that requires runtime-sizing of the array.
The core operation is % 10, which when applied to a number results in the rightmost digit (the "ones" digit).
You can do this by getting each digit and putting it into an array. Kudos to #unwind for thinking of using unsigned int because digits don't have signs. I didn't think of that.
DISClAIMER: this code is untested but would, theoretically, if I haven't made any mistakes that the community will catch, accomplish your task.
NOTE: This program is implementation-defined when theNum is negative. See this SO question for more info on what that means. Also, the accepted answer in the question of which this post is a duplicate has shorter code than this but uses log10 which (according to commenters) could be inaccurate.
//given theNum as the number
int tmp = theNum;
int magnitude = 0;
//if you keep dividing by 10, you will eventually reach 0 (integer division)
//and that will be the magnitude of the number + 1 (x * 10^n-1)
for (; tmp > 0; magnitude++){ //you could use a while loop but this is more compact
tmp /= 10;
}
//the number of digits is equal to the magnitude + 1 and they have no sign
unsigned int digits[magnitude];
//go backwards from the magnitude to 0 taking digits as you go
for (int i = magnitude - 1; i > 0; i--){
//get the last digit (because modular arithmetic gives the remainder)
int digit = theNum % 10;
digits[i] = digit; //record digit
theNum /= 10; //remove last digit
}
If this shall be done dynamically:
Determine the number of digits as N.
Allocate an array large enough (>=N) to hold the digits.
Loop N times chopping of the digits and storing them in the array allocated under 2.
The least significant digit is num % 10
The next digit can be found by num/=10;
This works for positive numbers, but is implementation defined for negative
I assume you want to achieve something like this:
int arr[SOME_SIZE];
int len = int_to_array(arr,421);
assert(len == 3);
assert(arr[0] == 4);
assert(arr[1] == 2);
assert(arr[1] == 1);
Since this is probably a homework problem, I won't give the full answer, but you'll want a loop, and you'll want a way to get the last decimal digit from an int, and an int with the last digit removed.
So here's a hint:
421 / 10 == 42
421 % 10 == 1
If you want to create an array of the right length, there are various approaches:
you could loop through twice; once to count digits (then create the array); once again to populate
you could populate an array that's bigger than you need, then create a new array and copy in as many members as necessary
you could populate an array that's bigger than you need, then use realloc() or similar (a luxury we didn't used to have!)

Homework about bit sequence in C

I have a homework. The question is:
Write a function that takes as parameter a single integer, int input, and returns an unsigned character
such that:
a- if input is negative or larger than 11,111,111 or contains a digit that is not 0 or 1; then the function will
print an error message (such as “invalid input”) and return 0,
b- otherwise; the function will assume that the base-10 value of input represents a bit sequence and return the magnitude-only bit model correspondent of this sequence.
For Example: If input is 1011, return value is 11 and If input is 1110, return value is 14
This is my work for a, and I am stuck on b. How can I get bit sequence for given integer input?
int main()
{
int input = 0;
printf("Please type an integer number less than 11,111,111.\n");
scanf("%d",&input);
if(input < 0 || input > 11111111)
{
printf("Invalid Input\n");
system("PAUSE");
return 0;
}
for (int i = 0; i < 8; i++)
{
int writtenInput = input;
int single_digit = writtenInput%10;
if(single_digit == 0 || single_digit == 1)
{
writtenInput /= 10;
}
else
{
printf("Your digit contains a number that does not 0 or 1. it is invalid input\n");
system("PAUSE");
return 0;
}
}
printf("Written integer is %d\n",input);
system("PAUSE");
return 0;
}
The bit that you are missing is the base conversion. To interpret a number in base B, what you need to do is multiply digit N times B^N (assuming that you start counting digits from the least significative). For example, in base 16, A108 = (10)*16^3 + 1*16^2 + 0*16^1 + 8*16^0. Where in your base is 2 (binary).
Alternatively, you can avoid the exponentiation if you rewrite the expression as:
hex A008 = ((((10*16) + 1)*16 +0)*16 + 8
Which would be simpler if your input was stated in terms of an array of possibly unknown length as it is easily convertible into a loop of only additions and multiplications.
In the particular case of binary, you can use another direct solution, for each digit that is non-zero, set the corresponding bit in an integer type large enough (in your case, unsigned char suffices), and the value of the variable at the end of the loop will be the result of the conversion.
First off, the existing part of your code needs work. It doesn't report non-binary digits correctly. The question is "Are there any digits that are neither 0 nor 1". To answer this question in the negative, you need to check every single digit. Your code can terminate early. I also suggest renaming the function to something that clearly tells you what it does. For example haveNonBinaryDigit. The term check doesn't tell you what you should expect on the return value.
As for the second part, read up on the binary representation. It is fairly similar to decimal, except that instead of each digit being weighted by 1, 10, 100, .., 10^x, they are weighted by 1, 2, 4, ..., 2^n. Also the digits can only have values 0 and 1.
Your current code has a problem: it will terminate as soon as it finds one single binary bit (at the end) and call the entire integer correct.
I would take a different approach to this problem. What you want to do is get your hands on every single digit from the integer seperately. You made a good start in doing so by using modulo. Say you had this code:
for (int i = 0; i < 8; i++)
{
char single_digit = input%10;
input /= 10;
}
This makes it easy to start working with the digits. You would be checking 8 bits because that seems to be the maximum allowed (11,111,111). Check if each digit is either 0 or 1. Then you can start pushing it in to an unsigned character using bitwise operations. Shift every digit to the left by i, then use a bitwise OR.

Resources