I've got an assignment where I have to sum whole numbers up to 100 digits.
They gave me this struct to represent big numbers (I think there are better ways to represent this, but I'm not allowed to modify it):
typedef struct {
char* string;
int lengthError;
} BigNumber;
Where string is the number itself and lengthError is the length of the number or an error that is a previously defined enum.
I've also have the implementation of the sum function
BigNumber *sum(BigNumber* num1, BigNumber* num2) {
BigNumber* result = malloc(sizeof(BigNumber));
int limit = getLength(num1->lengthError, num2->lengthError);
result->string = malloc(limit);
int digitResult;
int index = limit -1;
int carry = 0;
while(index != -1) {
int d1 = ((int)num1->string[index]) - ((int)'0');
int d2 = ((int)num2->string[index]) - ((int)'0');
digitResult = d1 + d2 + carry;
if (digitResult > 9) {
digitResult = digitResult - 10;
carry = 1;
} else {
carry = 0;
}
itoa(digitResult, &result->string[index], 10); //I think this is the problem
index--;
}
result->string[limit] = '\0';
printf("result: %s\n", result->string);
return result;
}
I haven't finished writing that function, I know there are a lot of flaws in it, but the problem is that I can't get to sum 12 + 12. The result I get is 2.
I thought approaching this problem by picking the lasts character of both numbers, transform them into an int and sum them having in mind the carry digit. After I got the result in digitResult I try to convert it to a char and store it in the corresponding position of the result->string pointer
Once it has finished the operation, I add an \0 at the last position of the result->string.
So the question is, how do I make this operation to work as desired? Debugging the code, I noticed that the first time it stores the first result in result->string, following the example above this would be a number 4, it stores trash in that position instead. In the second addition, I store a number 2 correctly and that's the final result I get in when I print the result.
Your use of the itoa function is a problem (though, as you have also suggested, maybe not the only one).
The itoa function converts its first argument into a null-terminated string - so, as well as writing the character representation of digitResult at the indicated place in the string, it also adds a '\0' character after it. Thus, your string will always be terminated immediately after the last digit you write, and 12 + 12, giving 24 will appear to be just the first character: 2.
What you can do instead is to convert the digit yourself (reversing the operation you used to get the d1 and d2 values), then just directly set the string element to the converted digit.
So, instead of:
itoa(digitResult, &result->string[index], 10);
use:
result->string[index] = (char)(digitResult + '0');
Related
I have to find the largest product of 13 adjacent numbers of a 1000-digit number below. My code for the problem is as follows:
#include <stdio.h>
int main()
{
char arr[1000] =
"731671765313306249192251196744265747423553491949349698352031277450"
"632623957831801698480186947885184385861560789112949495459501737958"
"331952853208805511125406987471585238630507156932909632952274430435"
"576689664895044524452316173185640309871112172238311362229893423380"
"308135336276614282806444486645238749303589072962904915604407723907"
"138105158593079608667017242712188399879790879227492190169972088809"
"377665727333001053367881220235421809751254540594752243525849077116"
"705560136048395864467063244157221553975369781797784617406495514929"
"086256932197846862248283972241375657056057490261407972968652414535"
"100474821663704844031998900088952434506585412275886668811642717147"
"992444292823086346567481391912316282458617866458359124566529476545"
"682848912883142607690042242190226710556263211111093705442175069416"
"589604080719840385096245544436298123098787992724428490918884580156"
"166097919133875499200524063689912560717606058861164671094050775410"
"022569831552000559357297257163626956188267042825248360082325753042"
"0752963450";
int i, j;
long int max;
max = 0;
long int s = 1;
for (i = 0; i < 988; i++) {
int a = 0;
for (j = 1; j <= 13; j++) {
printf("%c", arr[i + a]);
s = s * arr[i + a];
a++;
}
printf("%c%d", '=', s);
printf("\n");
if (s > max) {
max = s;
}
}
printf("\nMaximum product is %d", max);
getchar();
}
Some outputs are zero even if none of the input is zero. The second output happens to be negative. The answers don't even match. Any help is appreciated.
Many set of 13 digits in your char array arr contains zeroes and that is why the multiplication of these sets will result in 0.
There are a couple of issues with your code:
You are using %d instead of %ld to print long int. Using the wrong conversion specifier will result in undefined behaviour.
If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
You are not converting the ASCII value of the digit into its actual value before multiplication. (ASCII value of '0' is 48). This results in integer overflow and is the cause for negative values to be printed.
So the statement:
s = s * arr[i + a];
should be changed to:
s = s * (arr[i + a] - '0');
You are also not resetting the product s to 1 at the beginning of the inner for loop and because of this, you end up multiplying values from the results of different sets of 13.
After making these changes, you can see the live demo here.
There are a few issues to tackle in this code:
Clean up spacing and variable names (an edit by another user helped resolve this issue). Remove redundant variables like a, which j could easily represent by iterating from 0 to 12 rather than 1 to 13. This seems cosmetic but will make it easier for you to understand your program state, so it's actually critical.
Numerical overflow: As with all PE problems, you'll be dealing with extremely large numbers which may overflow the capacity of the long int datatype (231 - 1). Use unsigned long long to store your max and s (which I'd call product) variables. Print the result with %llu.
Convert chars to ints: arr[i+j] - '0'; so that you're multiplying the actual numbers the chars represent rather than their ASCII values (which are 48 higher).
s (really product) is not reset on each iteration of the inner loop, so you're taking the product of the entire 1000-sized input (or trying to, until your ints start to overflow).
I want to extract last 3 digit of a string suppose like :
char a[100][100] = ["17BIT0111" , "17BIT0222", ... n];
and I want to take last three digits and store in different array like
int b[100] =[111 , 222 , ... n];
I took reference from this but I wan't it without using pointer or a linked list. As I am gonna use it for comparing stack.
C program to extract different substrings from array of strings
Something like this:
for (int i = 0; i < 100; ++i)
{
unsigned int value = 0;
sscanf(a[i], "17BIT%u", &value);
b[i] = (int) (value % 1000);
}
This doesn't check the return value of sscanf(), instead defaulting the value to 0 in case conversion fails.
This will convert a larger integer, so the % 1000 was added to make sure only the last three digits really matter in the conversion. The unsigned is simply to disallow embedded dashes in the string, which makes sense to me in cases like these.
Sometimes we need to calculate very long number which couldn't hold any numerical data type of C. As we know all common numerical data type has limitation.
I'm beginner and I think... it is possible by string. My question is:
How can I add two strings?
Sample Input:
String 1: 1234
String 2: 1234
Output
Result : 2468
[Note: Numbers can be very very long in Strings. Unlimited]
Do not convert to a number. Instead, add as you (must) have learned in basic eductation: one pair of digits at a time, starting from the lowest (rightmost) and remember to carry the tens forwards (to the left).
The length of the source strings does not matter, but you must be sure the result char array is large enough for the longest input value plus one (optional) digit.
The algorithm is so simple that I will not "type the code" (which is off-topic for Stack Overflow). It boils down to
carryOver = 0
loop:
result0 = inputA0 + inputB0 + carryOver
if result0 > '9'
carryOver = 1
result0 -= 10
else
carryOver = 0
go to loop while there is still input left ...
where the 0 in the variable names indicate the index of the current digits under consideration.
Edit This Answer does not allow carry overs but infinity long add operations. It does not solve the problem of the user. But it is an implementation example and the user asked for one. This is why I will let the answer stay here and not delete it.
You can use atoi (ascii to int)
Do you realy mean C or C++?
This code can't calculate 8+3 = 11 but 5+3 = 8. There is no carry over.
int temp;
const inst size_of_array;
char one[size_of_array];
char two[size_of_array];
char result[size_of_array];
for(int i = 0; i < size_of_array; i++)
{
temp = atoi(one[i]) +atoi(two[i]);
results[i] = numberToCharacter(temp);
}
char numberToCharacter((int temp)
{
if(temp == 1)
{
return('1'):
} ///..
}
Parse the string variables to integer variables. Calculate sum of them, then parse the result to string.
Here is a fiddler.
Here is the code:
#include <stdio.h>
int main(void) {
//Declaring string variables
char string1[10] = "1234";
char string2[10] = "1234";
//Converting them to integer
int int1 = atoi(string1);
int int2 = atoi(string2);
//Summing them
int intResult = int1 + int2;
//Printing the result
printf("%d", intResult);
return 0;
}
I'm new to C and I need to write a function in c which converts an integer to a string in the specified base and print it.
If I were given an input value of 1234 (base 10) it should return 2322 (base 8).
Here is the code structure I'm currently working on:
void int2ascii(int value, int base){
int a=0;
if (value > base) {
a = a + int2char(value); //recursive case
int2ascii(value/base, base); //base case
}
printf("%s\n",a);
}
The program won't run, can someone enlighten me?
Thanks
Analysis of your program
I noted first off that a is declared int, but it was being passed to printf with %s as the format specifier. %s designates the associated argument will be a string, which a is not. The result will be undefined behavior, and is a possible cause for your crash.
You do not specify what int2char() does, but let's assume that it converts a numeric "digit" into a corresponding char value. With that in mind, let us suppose its implementation is similar to:
int int2char(int d) {
return "0123456789abcdefghijklmnopqrstuvwxyz"[d];
}
In your code, you pass value to int2char(). In my hypothetical implementation, this would cause out-of-bounds access of the array, and thus undefined behavior. This is indicates a logic error, and another possible cause for your crash.
I note that if value is less than base, a remains 0. Probably, you really mean to compute a value for a even when value is less than base. This indicates another logic error.
Base conversion
The number dKdK-1 .. d0, where each di is in (0 .. 9), is a short form for ∑di×10i. To discover the base 10 digits of a number N, the process is:
di = ⌊N / 10i⌋ mod 10
But, as it turns out, you can replace 10 with some other base number to compute the digits for a number in that base:
di = ⌊N / Bi⌋ mod B
In your code, the recursive call that divides by the base represents the first part of the calculation. However, in your calculation of a, you were missing the "mod" part of the calculation.
Solution 1
Assuming base is from 2 to 36, and that your int2char(d) does something more or less as illustrated earlier:
void int2ascii(int value, int base){
int a=0;
a = a + int2char(value%base);
if (value > base) {
int2ascii(value/base, base);
}
printf("%c",a);
}
Because you are not passing a into your recursive call, you can only use it to store the current digit to be printed. So, move the code to store the value in a out of the if check, since you always want a sensible value to print at the end. The digit in a is in the radix base, so you need the modulus result to get the right digit value. Since a represents a character, change the format string to match, and remove the \n so that all the digits end up on the same line.
Solution 2
The first solution is an attempt to leave most of your original code intact. Since a is initialized to 0, the extra addition does not make it incorrect. But, since the print doesn't happen until the very end, the value doesn't really need to be stored at all, and can be calculated at the point you actually want to print it. With that in mind, the program can be simplified to:
void int2ascii(int value, int base){
if (value > base) {
int2ascii(value/base, base);
}
printf("%c",int2char(value%base));
}
#include <stdio.h>
#include <limits.h>
char *int2ascii_aux(int n, int base, char *s){
//base {x| 2 <= x <= 36 }
static const char *table = "0123456789abcdefghijklmnopqrstuvwxyz";
if(n){
*--s = table[n % base];
return int2ascii_aux(n/base, base, s);
} else {
return s;
}
}
char *int2ascii(int n, int base){
//base {x| 2<= x <= 36 }
static char s[sizeof(int)*CHAR_BIT+1];
if(n <= 0){
*s = '0';
return s;
}
if(base < 2 || base > 36){
*s = '\0';
return s;
}
return int2ascii_aux(n, base, s + sizeof(s) -1);
}
int main(){
printf("%s\n", int2ascii(1234, 8));
return 0;
}
Hi I got this division alg to display the integer and floating point values.
How can I get MAX_REM? it is supposed to be the size of the buffer where our characters are going to be stored, so the size has to be the # of digits, but I don't know how to get that. thanks!
void divisionAlg(unsigned int value)
{
int MAX_BASE=10;
const char *charTable = {"0123456789ABCDEF"}; // lookup table for converting remainders
char rembuf[MAX_REM + 1]; // holds remainder(s) and provision null at the end
int index; //
int i; // loop variable
unsigned int rem; // remainder
unsigned int base; // we'll be using base 10
ssize_t numWritten; // holds number of bytes written from write() system call
base = 10;
// validate base
if (base < 2 || base > MAX_BASE)
err_sys("oops, the base is wrong");
// For some reason, every time this method is called after the initial call, rembuf
// is magically filled with a bunch of garbage; this just sets everything to null.
// NOTE: memset() wasn't working either, so I have to use a stupid for-loop
for (i=0; i<MAX_REM; i++)
rembuf[i] = '\0';
rembuf[MAX_REM] = 0; // set last element to zero
index = MAX_REM; // start at the end of rembuf when adding in the remainders
do
{
// calculate remainder and divide valueBuff by the base
rem = value % base;
value /= base;
// convert remainder into ASCII value via lookup table and store in buffer
index--;
rembuf[index] = charTable[rem];
} while (value != 0);
// display value
if ((numWritten = write(STDOUT_FILENO, rembuf, MAX_REM + 1)) == -1)
err_sys("something went wrong with the write");
} // end of divisionAlg()
The calculation for figuring out how many digits there are a number takes is:
digits = floor(log(number)/log(base))+1;
However, in this case, I'd probably just assume the worse case, since it's no more than 32, and calculating it will be "expensive". So just #define MAX_REM 32, and then keep track of how many digits you actually put into rembuf (you already have index for that, so it's no extra cost really). You'll obviously need to calculate the amount of bytes to write out as well, but shouldn't require any special math.