Thread: Adding a Large number digit by digit

  1. #16
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    Quote Originally Posted by Salem View Post
    Or just invert the test for even more simplicity, and perhaps a bit more obvious as to what it's about
    Code:
    if ( (number1[y] != 0) && (number2[y] != 0) ) {
        sum += carry;
        sum += number1[y] - '0' + number2[y] - '0';
        carry = sum / 10;
        result[y] = sum % 10 + '0';
        sum = 0;
    }
    True, I just prefer code where error/rare conditions are handled inside if statements. To me, that makes it clearer that the if statement handles abnormal conditions, and the rest of the code is free to execute and not dependent on an error *not* being true. A style difference, I guess

    Quote Originally Posted by matsp View Post
    In some cases, using the right way around of *p++ or *--p would perhaps cause better code on for example PDP-11, VAX or 68K, as those processors have "mov rA,(rB)+" and "mov rA,-(rB)", where the register rB is incremented/decremened automatically "at the same time as the access to memory" - but that would be specific to certain architectures, and definitely doesn't apply to the above case you described.
    I stand corrected. Apologies.

    QuantumPete
    Last edited by QuantumPete; 09-14-2007 at 04:34 AM. Reason: I should check my facts before posting...
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

  2. #17
    Registered User
    Join Date
    Oct 2005
    Posts
    17
    I'm having a tuff time figuring out how to pad the numbers with zeros after the user has input them. I was going to use strncpy and copy the string to itself, but the compiler doesn't like that.

    Can you guys give me a hint where or how to start it?

  3. #18
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Why not create a new string of the correct size, fill it with however many zeros you need for padding, and copy the old string after that?

    Or you might be able to do something like this, reusing the same string:
    Code:
    /* where:
        padding = number of zeros that need to be added to the string
        digits = number of digits currently in the string
        buffer = the number that needs to be padded --
            must have enough space for digits+padding digits plus a NULL
    */
    memmove(buffer + padding, buffer, digits);
    memset(buffer, '0', padding);
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #19
    Registered User
    Join Date
    Oct 2005
    Posts
    17
    How do I find how many digits are in the string after the user inputs them?
    The compiler won't let me use strlen because they are numbers. I"m not firing any other function to use.

  5. #20
    Registered User
    Join Date
    Oct 2005
    Posts
    17
    Here is my final code that I am turning in. I know it's a mess, but I have to turn it in just a few hours from now. Their was a lot of stuff I threw in because of problems with 0's and '0''s.
    Thank you for all your help. I couldn't of done it without the help. If you guys have suggestions on how I can improve this, I am still interested.

    Code:
    // CompE271HW2.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    
    int main(int argc, char* argv[])
    {
    unsigned char number1 [256] = {'0'};
    unsigned char number2 [256] = {'0'};
    unsigned char result [256] = {0};
    unsigned char result1 [256] = {0};
    int i, x, z, b, padding1, padding2, padding, y=0, sum, carry=0;
    
    //Allows user to input number
    printf ("Please enter a number upto 255 digits long:\n");
    scanf ("%s", number1);
    printf ("Your first number is %\s.\n",number1);
    
    printf ("Please enter another number upto 255 digits long:\n");
    scanf ("%s", number2);
    printf ("Your second number is %s.",number2);
    
    //Shifts the numbers so they are aligned to the right
    for (x= 0; number1[x] != 0; x++){
    	number1[x] = number1[x];
    	}
    	padding1 = 255 - x;
    	memmove(number1+padding1,number1,x);
    	memset(number1, 0, padding1);
    
    for (z= 0; number2[z] != 0; z++){
    	number2[z] = number2[z];
    	}
    	padding2 = 255 - z;
    	memmove(number2+padding2,number2,z);
    	memset(number2, 0, padding2);
    
    //Does the math
    	for(y=254; y>=0; y--) {		
    	if ( (number1[y] != 0) || (number2[y] != 0) ) {
    		if ( (number1[y] != 0) && (number2[y] != 0) ) {
    		sum = 0;
    		sum += carry;
    		carry = 0;
    		sum += number1[y] - '0' + number2[y] - '0';
    		carry = sum / 10;
    		result[y+1] = sum % 10 + '0';
    		}
    	else {
    	sum = 0;
    	sum += carry;
    	carry = 0;
        sum += number1[y] - '0' + number2[y];
        carry = sum / 10;
        result[y+1] = sum % 10 + '0';
    	}
    }
    
    //Adds the carry if left over
    if ((number1[y] == 0) && (number2[y] == 0) && (carry==1)){
    		result[y+1] = 1 + '0';
    		carry = 0;
    	}
    }
    
    //Shifts the digits back so a bunch of 0's are not leading the number.
    	for (b=255; result[b] != 0; b--){
    	result[b] = result[b];
    	}
    	padding = b+1;
    
    	memmove(result1,result+padding,255-b);
      printf("\nThe sum is %s.\n", result1);
    
      system ("PAUSE");
      return 0;
    }

  6. #21
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Code:
    #include "stdafx.h"
    That's non-standard, and you don't use anything from it. Your program should be able to compile without you including it. Try it.

    Code:
    unsigned char number1 [256] = {'0'};
    unsigned char number2 [256] = {'0'};
    unsigned char result [256] = {0};
    unsigned char result1 [256] = {0};
    When a compound initializer is missing some values, the remaining elements are filled with 0. This is why
    Code:
    int array[size] = {0};
    fills every element in array with zeros. However, this code
    Code:
    char string[size] = {'0'};
    will put '0' in the first element of string, and 0 is every element thereafter. Perhaps this was what you wanted -- it puts "0\0\0\0\0\0..." in the string after all, but I just thought I'd mention it. (If you do want to initialize every element in an array to something other than zero, either put every element in the initializer explicitly, or use something else like memset() or a for loop.)

    Code:
    //Allows user to input number
    printf ("Please enter a number upto 255 digits long:\n");
    scanf ("&#37;s", number1);
    printf ("Your first number is %\s.\n",number1);
    
    printf ("Please enter another number upto 255 digits long:\n");
    scanf ("%s", number2);
    printf ("Your second number is %s.",number2);
    scanf() is not the best way to read in a string. But I suppose you're not expecting anything other than digits, and you did say "up to 255 digits". Just as long as you know that that code is very fragile.

    Code:
    //Shifts the digits back so a bunch of 0's are not leading the number.
    	for (b=255; result[b] != 0; b--){
    	result[b] = result[b];
    	}
    The red code does nothing. You can leave the body of a for loop empty, so there's no need for it.

    The for loop could also "underrun" the beginning of the array if there are no elements set to zero in result[0]..result[255]. Of course, that shouldn't happen, but it would if the string had overrun the end of the array.

    Code:
    memmove(result1,result+padding,255-b);
    You do know what memmove() does, right? . . .

    I guess that your for loops before the memmove()s are to determine the length of the strings. You can use strlen() in place of them. They're strings. If your compiler doesn't let you then you must have been passing the wrong argument to strlen(). This
    Code:
    	for (b=255; result[b] != 0; b--){
    	result[b] = result[b];
    	}
    	padding = b+1;
    
    	memmove(result1,result+padding,255-b);
    should be able to be replaced with
    Code:
    	padding = strlen(result) + 1;
    
    	memmove(result1,result+padding,255-b);
    Code:
    for(y=254; y>=0; y--) {
    Why do you start at 254? Should that not be 255?

    Code:
    		sum = 0;
    		sum += carry;
    That's identical to
    Code:
    sum = carry;
    Code:
    sum += number1[y] - '0' + number2[y];
    Why don't you subtract '0' from number2[y]?

    Did you actually test this program? The not-subtracting-'0' bug would probably cause it to mess up . . .
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  7. #22
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by dwks View Post
    Code:
    #include "stdafx.h"
    But it may require turning off the "precompiled headers" setting, or changing some other settings regarding precompiled headers.

    Indentation is horrible:
    Code:
    for (x= 0; number1[x] != 0; x++){
    	number1[x] = number1[x];
    	}
    	padding1 = 255 - x;
    	memmove(number1+padding1,number1,x);
    	memset(number1, 0, padding1);
    This looks like the memmove and memset are part of the loop. I prefer:
    Code:
            for (x= 0; number1[x] != 0; x++){
    	   number1[x] = number1[x];
    	}
    	padding1 = 255 - x;
    	memmove(number1+padding1,number1,x);
    	memset(number1, 0, padding1);
    Of course, the for-loop in the above code can easily be replaced with:
    Code:
       x = strlen(number1);
    Also, there is no need to have x and z as variables for this and the next portion of code. Just use x for both loops. And just one "padding" variable.

    I would however, as I suggested earlier, make sure that both numbers are the same length, so that you don't have to mess about if the strings aren't equal length. Do this by sticking '0' at the beginning of the string.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #23
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Quote Originally Posted by matsp View Post
    But it may require turning off the "precompiled headers" setting, or changing some other settings regarding precompiled headers.
    Hence "should".

    Of course, the for-loop in the above code can easily be replaced with:
    Code:
       x = strlen(number1);
    I think I mentioned that, though perhaps it got lost in that mass of text . . .

    I would however, as I suggested earlier, make sure that both numbers are the same length, so that you don't have to mess about if the strings aren't equal length. Do this by sticking '0' at the beginning of the string.

    --
    Mats
    I believe that is what this code does:
    Code:
    //Shifts the numbers so they are aligned to the right
    for (x= 0; number1[x] != 0; x++){
    	number1[x] = number1[x];
    	}
    	padding1 = 255 - x;
    	memmove(number1+padding1,number1,x);
    	memset(number1, 0, padding1);
    
    for (z= 0; number2[z] != 0; z++){
    	number2[z] = number2[z];
    	}
    	padding2 = 255 - z;
    	memmove(number2+padding2,number2,z);
    	memset(number2, 0, padding2);
    It makes number1 and number2 both contain the same number of digits, right-aligned. Without it, the math code would be somewhat more complicated.

    Of course, it uses 0 where it should perhaps use '0', but the math code makes allowances for this.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  9. #24
    Registered User
    Join Date
    Oct 2005
    Posts
    17
    Thanks dwks for taking the time to help me improve.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. help with prime factor for 12 digit number
    By nick2 in forum C Programming
    Replies: 15
    Last Post: 06-19-2009, 04:39 AM
  2. Number Guessing
    By blacknapalm in forum C Programming
    Replies: 2
    Last Post: 10-01-2008, 01:48 AM
  3. Nim Trainer
    By guesst in forum Game Programming
    Replies: 3
    Last Post: 05-04-2008, 04:11 PM
  4. Need help getting program print out the digit in words
    By cosmiccomputing in forum C Programming
    Replies: 26
    Last Post: 04-24-2008, 08:28 AM
  5. Array of boolean
    By DMaxJ in forum C++ Programming
    Replies: 11
    Last Post: 10-25-2001, 11:45 PM