How to store a 13 digit number in c ?

P

Prasad

Hi,

Can anyone please tell me how to store a 13 digit number in C language
? Also what is the format specifier to be used to access this variable
?

Thanks in advance,
Prasad P
 
R

Richard Heathfield

Prasad said:
Hi,

Can anyone please tell me how to store a 13 digit number in C language
?

You have two choices:

(1) find a native type that's big enough;
(2) use a non-native representation (either by writing support for it
yourself, or by using existing third-party libraries).

C imposes no upper limits on native numerical types, but in practice those
limits do exist. So it imposes *minimum* upper limits instead, so that you
at least have a fighting chance!

In C90, no native integer type (and I'm guessing that we're talking about
integers here) is required to be able to store 13-decimal-digit numbers,
although all of them are allowed to, so if you are using C90 or are
required to retain portability to C90 implementations, you are stuck with
option (2). Either write your own bignum package, or use something like GMP
or Miracl.

In C99, you can use long long int or its unsigned partner, which must be at
least 64 bits wide (but can be wider), and so they are easily capable of
storing 13-decimal-digit numbers. (But beware! Some C90 compilers also
offer long long int (or an equivalent) as an extension. Doing so does not
magically turn them into C99 compilers.)
Also what is the format specifier to be used to access this variable?

For GMP and Miracl, consult the documentation for techniques for writing the
value to, or reading from, a stream.

For C99's long long int and unsigned long long int, use %lld and %llu
respectively.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: normal service will be restored as soon as possible. Please do not
adjust your email clients.
 
F

Frederick Gotham

Prasad:
Can anyone please tell me how to store a 13 digit number in C language
?

You haven't specified the radix of the number system. However, I think it's
safe to assume that you're human and that you've got 10 fingers, so we'll
go with that one for a minute.

I'm not sure if Standard C provides an unsigned integer type which must
have at least 44 value representation bits. (If it does, then it's probably
"int unsigned long long").

I can think of a simple method of achieving what you want (although
somewhat inefficient), which is the use of binary-coded decimal. The radix
must be below 257 for the following to work on any implementation:

(Unchecked code, sloppily written, probably won't even compile.)

#include <limits.h>

#define RADIX (10)
#define DIGIT_BIT (4) /* A better way than hardcoding 4? */
#define DIGIT_PER_BYTE (CHAR_BIT/DIGIT_BIT)

#define DIGIT_BIT_MASK (~(UINT_MAX << DIGIT_BIT))

typedef struct ThirteenDigitNum {
char unsigned digits[13/DIGIT_PER_BYTE + !!(13%DIGIT_PER_BYTE)];
} ThirteenDigitNum;

typdef struct DigitAccessInfo {
unsigned byte_index;
unsigned shift_by;
unsigned mask;
};

void SetDAI(DigitAccessInfo *const p,unsigned const index)
{
p->byte_index = index / DIGIT_PER_BYTE,
p->shift_by = CHAR_BIT * index % DIGIT_PER_BYTE;
p->mask = DIGIT_BIT_MASK << shift_by;
}

unsigned GetDigit(ThirteenDigitNum const *const p,unsigned const index)
{
DigitAccessInfo dai; SetDai(&dai,index);

return (*p->digits[dai.byte_index] & dai.mask) >> dai.shift_by;
}

void SetDigit(ThirteenDigitNum const *const p,unsigned const index,
unsigned const val)
{
DigitAccessInfo dai; SetDai(&dai,index);

*p->digits[dai.byte_index] &= ~dai.mask;

*p->digits[dai.byte_index] |= val << dai.shift_by;
}
 
T

Tor Rustad

Prasad skrev:
Hi,

Can anyone please tell me how to store a 13 digit number in C language

char number[14];
? Also what is the format specifier to be used to access this variable

printf("%s", number);


If there is a need to do arithmetic, you need to do radix 256 math, an
example of such is given in "Numerical Recipes in C". More efficient
multi-precision packages exsist, see for example the lip package by
Arjen K. Lenstra. If you want to implement such a package, take a look
in Knuth "TAoCP".
 
K

Keith Thompson

Frederick Gotham said:
Prasad:

You haven't specified the radix of the number system. However, I think it's
safe to assume that you're human and that you've got 10 fingers, so we'll
go with that one for a minute.

I'm not sure if Standard C provides an unsigned integer type which must
have at least 44 value representation bits. (If it does, then it's probably
"int unsigned long long").
[...]

Everyone else refers to that type as "unsigned long long" or "unsigned
long long int". Drop the "unsigned" if you want to be able to
represent negative numbers.

The language, for some reason, allows you to use the keywords in a
different order. Frederick Gotham is the *only* person I know of who
does this. If you want others to be able to read your code easily,
it's best to follow normal conventions.

And yes, "long long" and "unsigned long long" are guaranteed to be at
least 64 bits. They're standard in C99, and a common (but not
universal) extension in C90 compilers.
 
P

pete

Everyone else refers to that type as "unsigned long long" or "unsigned
long long int". Drop the "unsigned" if you want to be able to
represent negative numbers.

The language, for some reason, allows you to use the keywords in a
different order. Frederick Gotham is the *only* person I know of who
does this. If you want others to be able to read your code easily,
it's best to follow normal conventions.

I write (long unsigned) instead of (unsigned long)
to help me to remember to write %lu instead of %ul,
which is a mistake that I've made once or twice.
 
K

Keith Thompson

Tor Rustad said:
Prasad skrev:
Hi,

Can anyone please tell me how to store a 13 digit number in C language

char number[14];
? Also what is the format specifier to be used to access this variable

printf("%s", number);

If there is a need to do arithmetic, you need to do radix 256 math, an
example of such is given in "Numerical Recipes in C". More efficient
multi-precision packages exsist, see for example the lip package by
Arjen K. Lenstra. If you want to implement such a package, take a look
in Knuth "TAoCP".

If you're going to do radix 256 math, you should declare the array as
unsigned char, not char.

But since 13 decimal digits will fit in less than 64 bits, you should
almost always be able to use plain integer types rather than some
multi-precision package (unless you have a C90 compiler that doesn't
provide a 64-bit integer type, either as an extension or as "long").
 
C

Chris McDonald

Are you writing for an 8-bit processor, because it wasn't clear
how many bits are provided by your 'long long' construction.
Why not take the little effort, and use an int64_t ?
 
K

Keith Thompson

Chris McDonald said:
Are you writing for an 8-bit processor, because it wasn't clear
how many bits are provided by your 'long long' construction.
Why not take the little effort, and use an int64_t ?

In any conforming C99 implementation, unsigned long long is guaranteed
to be at least 64 bits.

Many non-C99 implementations provide (unsigned) long long as an
extension. I would expect them to make it at least 64 bits (there's
no point in defining it otherwise) -- and I wouldn't be surprised if
an implementation provided long long but *didn't* provide <stdint.h>
or (u)int64_t. Of course, you can always define (u)int64_t yourself
if the implementation doesn't.

Bottom line: (unsigned) long long is probably more portable than
(u)int64_t, and is very unlikely to be less than 64 bits.
 
R

Richard Heathfield

Keith Thompson said:

Many non-C99 implementations provide (unsigned) long long as an
extension. I would expect them to make it at least 64 bits (there's
no point in defining it otherwise)

IMHO there's no point in defining it /at all/. They can simply make long int
64 bits wide instead. Or more.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: normal service will be restored as soon as possible. Please do not
adjust your email clients.
 
T

Tor Rustad

Keith Thompson skrev:
If you're going to do radix 256 math, you should declare the array as
unsigned char, not char.

The example in "Numerical Recipes in C" do use unsigned char.
But since 13 decimal digits will fit in less than 64 bits, you should

Most people don't work at a Supercomputer Center... :) Why would OP
ask, if having a C compiler with 64-bit integers?
almost always be able to use plain integer types rather than some
multi-precision package (unless you have a C90 compiler that doesn't
provide a 64-bit integer type, either as an extension or as "long").

When did compiler extensions become on-topic and "long" able to hold a
64-bit integers in c.l.c? *shocked*

I currently use at least 5 different C compilers, none provide a 64-bit
integer type "long long". Also, I checked
http://gcc.gnu.org/c99status.html... not much progress last 3 years
there, which C99 compiler do "almost" everybody use these days?
 
K

Keith Thompson

Richard Heathfield said:
Keith Thompson said:


IMHO there's no point in defining it /at all/. They can simply make long int
64 bits wide instead. Or more.

Unfortunately, there's a lot of (poorly written) code out there that
makes unwarranted assumptions about the sizes of the predefined types.
Catering to such code is an unfortunate necessity, but it's a
necessity nonetheless.
 
M

Max TenEyck Woodbury

Tor said:
When did compiler extensions become on-topic

A long-long time ago. (word play intended!)
and "long" able to hold a 64-bit integers in c.l.c? *shocked*

From the beginning. The standard sets minimums, but not
maximums for the number of bits in each integer type.
I currently use at least 5 different C compilers, none provide a 64-bit
integer type "long long". Also, I checked
http://gcc.gnu.org/c99status.html... not much progress last 3 years
there, which C99 compiler do "almost" everybody use these days?

GCC has had 'long long' for the better part of a decade, if not
longer. Of course it has not changed in the last 3 years.

Now Microsoft on the other hand has been a bit slow on the
uptake, but that is to be expected...
 
R

Richard Heathfield

Keith Thompson said:

Unfortunately, there's a lot of (poorly written) code out there that
makes unwarranted assumptions about the sizes of the predefined types.
Catering to such code is an unfortunate necessity, but it's a
necessity nonetheless.

At least one implementor has demonstrated that 64-bit longs (and ints, and
shorts) are viable.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: normal service will be restored as soon as possible. Please do not
adjust your email clients.
 
T

Tor Rustad

Max TenEyck Woodbury skrev:
Tor Rustad wrote:

From the beginning. The standard sets minimums, but not
maximums for the number of bits in each integer type.

LONG_MAX... gives the maximum value for "long" in portable C programs.

I used 64-bit "int" 16 years ago on Cray, but that was very much
non-portable, still is, except for someone porting programs among
super-computers. :)
GCC has had 'long long' for the better part of a decade, if not
longer. Of course it has not changed in the last 3 years.

Support for "long long", doesn't make it a C99 compiler.
 
I

Ian Collins

Tor said:
Max TenEyck Woodbury skrev:



LONG_MAX... gives the maximum value for "long" in portable C programs.

I used 64-bit "int" 16 years ago on Cray, but that was very much
non-portable, still is, except for someone porting programs among
super-computers. :)
64 bit long is the norm on 64 bit desktop/servers these days.
 
M

Max TenEyck Woodbury

Tor said:
Max TenEyck Woodbury skrev:


LONG_MAX... gives the maximum value for "long" in portable C programs.

Exactly, and the standard specifies a minimum value for it that assures
that 'long' will contain at least 32 bits. Larger values, with more
bits is allowed.
Support for "long long", doesn't make it a C99 compiler.

scuse please; you brought up GCC and mentioned 'long long' in
relation to it. 'long long' is in the C99 standard. You also
said something about GCC not having changed in 3 years. That
implied that 'long long' was not implemented in GCC. I pointed
out that it had been implemented.

As for GCC being C99 compliant, there have been a few changes
in the last year or so and it does claim to be a C99 compiler
in one of its modes. (-std=c99 or something like that.) They
are not great documenters so I'm not at all surprised that they
have not updated their 'status' page.

Chill...
 
J

J. J. Farrell

Tor said:
Keith Thompson skrev:

Most people don't work at a Supercomputer Center... :)

So? Most modern general-purpose computers support 64-bit native
integers, and many high-end ones have for many years. It's well over a
decade since "64-bit int" implied "supercomputer".
Why would OP ask, if having a C compiler with 64-bit integers?

The OP asked how to store a 13 digit number and gave no clue as to the
level of his knowledge. Putting it in a 64-bit integer type is an
obvious way to do it, but there's no reason to believe the OP was aware
of that.
When did compiler extensions become on-topic and "long" able to hold a
64-bit integers in c.l.c? *shocked*

When c.l.c was created. Why be shocked?
I currently use at least 5 different C compilers, none provide a 64-bit
integer type "long long".

I find that very suprising. Most of the compilers I use provide it.
Also, I checked
http://gcc.gnu.org/c99status.html... not much progress last 3 years
there, which C99 compiler do "almost" everybody use these days?

Almost nobody uses a C99 compiler these days. What made you think
"almost" everybody does?
 
J

Jordan Abel

2006-11-10 said:
Exactly, and the standard specifies a minimum value for it that assures
that 'long' will contain at least 32 bits. Larger values, with more
bits is allowed.

scuse please; you brought up GCC and mentioned 'long long' in
relation to it. 'long long' is in the C99 standard. You also
said something about GCC not having changed in 3 years. That
implied that 'long long' was not implemented in GCC. I pointed
out that it had been implemented.

As for GCC being C99 compliant, there have been a few changes
in the last year or so and it does claim to be a C99 compiler
in one of its modes. (-std=c99 or something like that.) They
are not great documenters so I'm not at all surprised that they
have not updated their 'status' page.

The things that page says don't work, still don't work.

Now, that list is actually quite short:

wide character library support in <wchar.h> and <wctype.h> (originally
specified in AMD1) (Library Issue, Missing)
variable-length arrays (Broken)
complex (and imaginary) support in <complex.h> (Broken)
extended identifiers (Missing)
extended integer types in <stdint.h> (Missing)
additional math library functions in <math.h> (Library Issue, Missing)
IEC 60559 (also known as IEC 559 or IEEE arithmetic) support (Broken)
inline functions (Broken)
additional predefined macro names (Missing)
standard pragmas (Missing)

And a lot of them are partially supported.
 
C

Clark S. Cox III

Chris said:
Are you writing for an 8-bit processor, because it wasn't clear
how many bits are provided by your 'long long' construction.

On any C99 compiler, long long is *always* at least 64-bits. Period.
Why not take the little effort, and use an int64_t ?

Because we don't need it to be *exactly* 64-bits, we just need it to be
*at least* 44-bits.
 

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

No members online now.

Forum statistics

Threads
474,436
Messages
2,571,696
Members
48,796
Latest member
Greg L.
Top