Add 4 20 digit numbers in C

T

thehobbit

Hi,

Could anyone give ideas on how to add 4 20 digit numbers in ANSI C and
pass the result back to a calling program in COBOL? We were able to
add up to 15 digit numbers without any problems, but we started facing
issues once we go above 15 digits.

Thanks,
Venkat
 
J

Jack Klein

Hi,

Could anyone give ideas on how to add 4 20 digit numbers in ANSI C and
pass the result back to a calling program in COBOL? We were able to
add up to 15 digit numbers without any problems, but we started facing
issues once we go above 15 digits.

ANSI C, or ISO C, or just plain standard C, does not define linkage to
COBOL or any other language. So there is no way to do this in "ANSI
C".

On the other hand, you may have an issue with numeric precision in the
C implementation you are using, regardless of how you are getting the
values into the C program.

But you haven't provided nearly enough information. What types are
these numbers? Integers, floating point, what? What data type are
they defined as in C?

And you haven't told us what "problems" you think you are having.

How many digits does the C data type you are using have?

If this is an integer type, you can look at the type_MAX macro in
<limits.h> to tell you what the range of values the type can handle
is.

If you are using one of the floating point types, look at type_DIG in
<float.h>.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
T

thehobbit

Thank you for the details jack... actually am a nincompoop in C...
more of a COBOL programmer... actually what we are trying to do is add
4 20 digit integers and return the sum back to the COBOL program. This
is because COBOL has a limitation of 18 digits. When we added 15 4
digit integer numbers we got the expected sum, however the moment we
started adding 16 4 digit integers then the sum was all wrong... the
code we kind of wrote is as follows; Please let us know if you have
any suggestions...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* Function to add 4 integers
*/

void ccadd(char *inp1,char *inp2,char *inp3,char *inp4,char *out)
{
long long int_inp1,int_inp2,int_inp3,int_inp4,int_out;
int_inp1 = atoi(inp1);
int_inp2 = atoi(inp2);
int_inp3 = atoi(inp3);
int_inp4 = atoi(inp4);

int_out = int_inp1 + int_inp2 + int_inp3 + int_inp4;
sprintf(out,"%lf",int_out);
}
 
I

Ian Collins

thehobbit wrote:

In future, please don't top post.
Thank you for the details jack... actually am a nincompoop in C...
more of a COBOL programmer... actually what we are trying to do is add
4 20 digit integers and return the sum back to the COBOL program. This
is because COBOL has a limitation of 18 digits. When we added 15 4
digit integer numbers we got the expected sum, however the moment we
started adding 16 4 digit integers then the sum was all wrong... the
code we kind of wrote is as follows; Please let us know if you have
any suggestions...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* Function to add 4 integers
*/

void ccadd(char *inp1,char *inp2,char *inp3,char *inp4,char *out)

Make the inputs const char*.
{
long long int_inp1,int_inp2,int_inp3,int_inp4,int_out;
int_inp1 = atoi(inp1);

Don't use atoi to convert a C string to long long, use strtoll, or if
you are 100% sure the C strings represent valid numbers, atoll.
 
T

thehobbit

thehobbit wrote:

In future, please don't top post.






Make the inputs const char*.


Don't use atoi to convert a C string to long long, use strtoll, or if
you are 100% sure the C strings represent valid numbers, atoll.

thanks... i am sure that they represent valid numbers.. but not able
to use atoll function on my system (called HP3000)... gives a run time
error. any particular library needs to be included when using the
atoll function?
 
R

Richard Heathfield

thehobbit said:
thanks... i am sure that they represent valid numbers.. but not able
to use atoll function on my system (called HP3000)... gives a run time
error. any particular library needs to be included when using the
atoll function?


Ian was working on the incorrect assumption that you have access to a C99
compiler. It is odd that he should assume this, since practically nobody
has access to a C99 compiler.

The problem you are having is that the numbers you wish to add are too big
to fit into any of the integer types you appear to have available on your
system, and too big to fit *exactly* into any of the floating point types.

It's at times like this that you need to reach for your friendly
neighbourhood "bignum" library, such as GMP (Gnu Maths Package, I think)
or Miracl. These libraries provide the functionality you need. (If you
don't like that answer, you could do what I did, which is to write your
own bignum library - and, if all you want to do is add two (or more) big
numbers together, it's pretty easy to do that yourself. Just think about
how you stop overflow. In fact, just think about how you don't even
*consider* overflow when adding numbers with pencil and paper. It's never
an issue, is it? Why not? Because you have more paper on the left, that's
why, and you allocate enough for your needs, which you can more or less
work out in your head (for any two numbers neither of which is more than D
digits long, D + 1 digits will suffice to store the answer, sometimes with
room to spare).
 
I

Ian Collins

Richard said:
thehobbit said:



Ian was working on the incorrect assumption that you have access to a C99
compiler. It is odd that he should assume this, since practically nobody
has access to a C99 compiler.
It seamed a fair assumption as he was using long long. I don't know
about other platforms, but Solaris has had these function for at least a
decade. I'm sure most people here have access to systems with strtoll
and compilers with long long, fully C99 compliant or not.
 
R

Richard Heathfield

Ian Collins said:
Richard Heathfield wrote:

It seamed a fair assumption as he was using long long.

Ian, I apologise. I am guilty of not reading the thread history carefully
enough. He does indeed use long long int in his own code, and what was
needed was indeed a C99 usage lesson rather than a bignum package.

<snip>
 
N

Nick Keighley

don't top post. I've rearranged things



don't quote sigs (the bit after ("-- ")

Thank you for the details jack... actually am a nincompoop in C...
more of a COBOL programmer... actually what we are trying to do is add
4 20 digit integers and return the sum back to the COBOL program. This
is because COBOL has a limitation of 18 digits. When we added 15 4
digit integer numbers we got the expected sum,

? confusion

if you want to add 4 20-digit numbers why are you adding 4-digit
numbers?

however the moment we
started adding 16 4 digit integers then the sum was all wrong...

could you give an example of the numbers you used that gave the wrong
answer?

the code we kind of wrote is as follows;

this code doesn't add 16 numbers


Please let us know if you have
any suggestions...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* Function to add 4 integers
*/

void ccadd(char *inp1,char *inp2,char *inp3,char *inp4,char *out)

this is more of a style point. Why not use an array? And since your
program doesn't change the input values make it const.

void ccadd (const char *inp[], int in_count, char *out)

{
long long int_inp1,int_inp2,int_inp3,int_inp4,int_out;
int_inp1 = atoi(inp1);

atoi() has poor error checking. And it doesn't return a long long.
Use a strtoX() function. And use one that returns a long long
or unsigned long long. Check for errors.

int_inp2 = atoi(inp2);
int_inp3 = atoi(inp3);
int_inp4 = atoi(inp4);

int_out = int_inp1 + int_inp2 + int_inp3 + int_inp4;
sprintf(out,"%lf",int_out);

}

try posting a complete program and its results
 
I

Ian Collins

*Please* don't quote signatures.
thanks... i am sure that they represent valid numbers.. but not able
to use atoll function on my system (called HP3000)... gives a run time
error. any particular library needs to be included when using the
atoll function?
Ah, I didn't spot the runtime error bit, what error do you see? I
strongly recommend you use strtoll and check for errors. If this still
gives you an error, post the code, test data and the error. The
function should be part of your standard library and not require
additional libraries (it would fail to link otherwise), check your
documentation.
 
B

Ben Bacarisse

Please don't keep quoting sigs.
thanks... i am sure that they represent valid numbers.. but not able
to use atoll function on my system (called HP3000)... gives a run time
error. any particular library needs to be included when using the
atoll function?

I have not heard of atoll but some versions of HP-UX do seem to be
missing strtoll. It would appear they have strtoimax[1] which is a
POSIX function to do the same job. I say "seem" and "appear to"
because I don't know -- I just did the web search you should have done
when you found the answer was a function that seems to be missing --
strtoll.

[1] http://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html
 
C

CBFalconer

thehobbit said:
Thank you for the details jack... actually am a nincompoop in C...
more of a COBOL programmer... actually what we are trying to do is
add 4 20 digit integers and return the sum back to the COBOL
program. This is because COBOL has a limitation of 18 digits. When
we added 15 4 digit integer numbers we got the expected sum,
however the moment we started adding 16 4 digit integers then the
sum was all wrong... the code we kind of wrote is as follows;
Please let us know if you have any suggestions...

Top-posting has lost all the previous content. Please avoid it.

You are not adding integers - you are adding strings. Your problem
is double. First arrange to cleanly limit the input strings, i.e.
detect the rightmost and leftmost digits in each. Then you can
simply perform sequential addition, adding individual digits and
propagating carries. You have to be able to drop propagation past
the most significant digit of the input.

Please do not top-post. Your answer belongs after (or intermixed
with) the quoted material to which you reply, after snipping all
irrelevant material. See the following links:

--
<http://www.catb.org/~esr/faqs/smart-questions.html>
<http://www.caliburn.nl/topposting.html>
<http://www.netmeister.org/news/learn2quote.html>
<http://cfaj.freeshell.org/google/> (taming google)
<http://members.fortunecity.com/nnqweb/> (newusers)
 
W

Willem

thehobbit wrote:
) Thank you for the details jack... actually am a nincompoop in C...
) more of a COBOL programmer... actually what we are trying to do is add
) 4 20 digit integers and return the sum back to the COBOL program. This
) is because COBOL has a limitation of 18 digits. When we added 15 4
) digit integer numbers we got the expected sum, however the moment we
) started adding 16 4 digit integers then the sum was all wrong... the
) code we kind of wrote is as follows; Please let us know if you have
) any suggestions...

Can't you roll your own bignum function in cobol ?
That is, one that adds four 'strings' together that consist of difits.
I mean, just adding numbers is quite easy.

Here's a snippet in C that does the same.
I'm sure you can easily rewrite that to COBOL.
It could even be made a lot simpler by right-aligning the numbers,
so you don't first have to find the length.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* Function to add 4 integers
* Assumes the integers contain only digits '0' through '9'.
*/

void ccadd(char *inp1,char *inp2,char *inp3,char *inp4,char *out)
{
int res;
size_t i1, i2, i3, i4, io;

i1 = strlen(inp1);
i2 = strlen(inp2);
i3 = strlen(inp3);
i4 = strlen(inp4);
io = i1;
if (i2 > io) io = i2;
if (i3 > io) io = i3;
if (i4 > io) io = i4;
io = io + 1;

out[io] = 0;
res = 0;

while (io > 0) {
if (i1 > 0) res += (inp1[--i1] - '0');
if (i2 > 0) res += (inp2[--i2] - '0');
if (i3 > 0) res += (inp3[--i3] - '0');
if (i4 > 0) res += (inp4[--i4] - '0');
out[--io] = (res % 10) + '0';
res = res / 10;
}
}

SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
T

Tor Rustad

thehobbit said:
Hi,

Could anyone give ideas on how to add 4 20 digit numbers in ANSI C and
pass the result back to a calling program in COBOL? We were able to
add up to 15 digit numbers without any problems, but we started facing
issues once we go above 15 digits.

Using an old COBOL compiler?

I while back, I took a look at IBM's decNumber C library:

http://www2.hursley.ibm.com/decimal/decnumber.html

which provide an implementation of the upcoming IEEE 754 revision. I
haven't used it yet, but if there are issues with the library, there are
tons of multi-precision C packages out there, see e.g. GNU GMP.

How to interface, COBOL and C, is specified in your platform doc, we
cannot tell.
 
C

Charlie Gordon

thehobbit said:
Thank you for the details jack... actually am a nincompoop in C...
more of a COBOL programmer... actually what we are trying to do is add
4 20 digit integers and return the sum back to the COBOL program. This
is because COBOL has a limitation of 18 digits. When we added 15 4
digit integer numbers we got the expected sum, however the moment we
started adding 16 4 digit integers then the sum was all wrong... the
code we kind of wrote is as follows; Please let us know if you have
any suggestions...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* Function to add 4 integers
*/

void ccadd(char *inp1,char *inp2,char *inp3,char *inp4,char *out)
{
long long int_inp1,int_inp2,int_inp3,int_inp4,int_out;
int_inp1 = atoi(inp1);
int_inp2 = atoi(inp2);
int_inp3 = atoi(inp3);
int_inp4 = atoi(inp4);

You should use atoll or stroll for these conversions if the numbers can
exceed INT_MAX
int_out = int_inp1 + int_inp2 + int_inp3 + int_inp4;
sprintf(out,"%lf",int_out);

Here you are using the wrong format: it should be %lld assuming your C
library supports long long
Also there is no guarantee the result of the conversion will "fit" in the
destination buffer ``out''.

The format error may well be the source of your problem, but the solution
posted by Willem is more general, as it can handle numbers of any size
(still assuming the destination is large enough)
 
U

user923005

Thank you for the details jack... actually am a nincompoop in C...
more of a COBOL programmer... actually what we are trying to do is add
4 20 digit integers and return the sum back to the COBOL program. This
is because COBOL has a limitation of 18 digits. When we added 15 4
digit integer numbers we got the expected sum, however the moment we
started adding 16 4 digit integers then the sum was all wrong... the
code we kind of wrote is as follows; Please let us know if you have
any suggestions...

The reason that COBOL has a limit of 18 digits is because the data
type has a limit of 18 digits.
A long long integer (or unsigned long long) generally consumes 8 bytes
of memory storage.
That means that you can store {typically} 2^64-1 in an unsigned long
long. Let's see what it looks like:
unsigned limit = 18446744073709551615 (We are unable to store
99999999999999999999 so 19 digits precision)
signed limit = 9223372036854775807 (We are unable to store
9999999999999999999 so 18 digits of precision)

C probably will not have any more success than COBOL at adding your
numbers together, because if they overflow in COBOL then they will
overflow in C.

So the real question is, "What is the exact problem that you are
trying to solve?" Chances are very good that the problem can be
solved in either COBOL or C or both.

If you need to store a 20 digit number in a comp type that occupies 8
bytes, then often you will meet with serious disappointment.
So what we need to know is, is this a total for a report? Is it a
value to be posted back to the database? Exactly what is the purpose
of the new total?
Once we know that, then you can decide on an algorithm to solve the
problem or a new data type for the database, or whatever.

Probably, your posts are more topical in
[snip]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,045
Latest member
DRCM

Latest Threads

Top