why pointer variable not showing 100 digits? [duplicate] - c

aim: i had a requirement for accuracy i need 100 digits to be displayed or atleast 50 digits
try 1: first i had used integer variable then it displayed only 10 digits
try 2: with the help of my friend i used pointers concept it successfully had input 50 to 100 digits but pointer variable display only 10 digits
the program i had written was
#include <stdio.h>
#include <string.h>
main()
{
int *p;
p=(int*)malloc(100*sizeof(int));
*p=1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890;
printf("%d",*p);
}
on executing the above procedure i'm getting a garbage value
thanks in advance

You need to use a bignum (arbitrary precision big numbers) library, since native int or long have a precision limited by the C implementation - ie the hardware (often 32 or 64 bits; see also <stdint.h> header and int32_t & int64_t types). I suggest using GMPlib; you need to be fluent in C to use such libraries. Read documentation of GMLib.
Don't try to code bignumber arithmetic yourself. You'll use inefficient algorithms. Efficient algorithms for bignums are difficult to understand and to invent. You can still get a PhD on that. So use some existing bignum library.
So you might code something like the following to multiply your bignum by 137 and print the result
mpz_t bign;
mpz_t bigr;
// initialize bign from a literal string
mpz_init_set_str (bign,
"12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890",
10);
// initialize bigr
mpz_init(bigr);
/// compute bigr = bign * 137 (137 is a long, not a bignum)
mpz_mul_si(bigr, bign, 137L);
/// print bigr on stdout in base 10
mpz_out_str (stdout, 10, bigr);
/// clear all the numbers
mpz_clear(bign);
mpz_clear(bigr);
On a Linux system with GMP installed, you could compile such a code (in yoursource.c) using:
gcc -Wall -Wextra -g yoursource.c -lgmp -o yourprog
On other systems you might need some -I and -L arguments to gcc. When you have debugged your program, ask the compiler to optimize it with -O2
Notice that some languages (Common Lisp, Scheme, Python) have built-in bignums.
BTW, your main function is incorrectly defined. It should be defined as int main(int argc, char**argv) ...

To answer the first part, a single signed integer (assuming 32 bits) can take values between -2,147,483,648 and +2,147,483,647
This is where your ten digits comes from.
Depending on your compiler, you may have unsigned long long available (64 bits) but that still only offers you a maximum or 0..18,446,744,073,709,551,615 (20 digits)
To handle 100-digit numbers will require some jiggery-pokery!

int * p = malloc(100*sizeof(int));
Allocates memory for an array of 100 int.
*p= ....
In fact is the same as
p[0]=...
So this
*p=1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890;
assigns to an int.
An int may hold not more then a 32 bits (less on some platforms). The largest 32bit (positive) integer is 2147483647.

C is a language close to the hardware. So you need to understand the storage capabilities and limitations of its data types.
An int on a PC is only able to store 32 bit or 64 bit values, depending on your hardware and OS version.
Yes, you can implement routines for handling larger value, and using a linked list of digits is one way do it.

You can't store such a long digit in an int variable or a pointer which is pointing to type int.
If int is of 32 bit, the range is [−2147483647,+2147483647]. C data types
To store the large value you can use a char pointer and initialized it with the string constant.
For example:
#include <stdio.h>
#include <stdlib.h>
main()
{
char *p = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
printf("%s\n",p);
}

Related

Loadrunner Epoch time to Hexadecimal

I am looking for a way to convert epoch time in decimal to hexadecimal
(for example: decimal = 1417502160098 and hexadecimal = 14a09b674e2).
Loadrunner script is using hexadecimal value to get the latest image.
I am finding this difficult as there is no identifier in c to weight the decimal value of 13 digits.
Please let me know if any one has tried this in Loadrunner.
There is an 64-bit integer type in C. It's called int64_t and can be used like this:
#include <stdio.h>
#include <inttypes.h>
int main(void)
{
int64_t epoch = 1417502160098LL;
printf("%" PRIx64 "\n", epoch);
return 0;
}
As noted above, you need C code to do this. Although you need a set of code which is both 32 bit and 64 bit compliant, so the use of the 64 bit integer type is not likely to be of much use in this case.
This conversion from one numerical base to another is a fairly common exercise for first year programming students in college, so you may find a routine in any number of textbooks. I am also including a link to a sample (untested/unvalidated)
http://www.programiz.com/c-programming/examples/hexadecimal-decimal-convert
I'm not at all sure what you mean by "there is no identifier in c to weight the decimal value of 13 digits".
However, if you want to do this in C code, you would typically use the snprintf() function to convert a variable's value to a string of hexadecimal digits:
#include <stdio.h>
#include <inttypes.h>
const uint64_t value = 1417502160098UL;
char hexbuf[32];
snprintf(hexbuf, sizeof hexbuf, "%" PRIx64, value);
UPDATE: If you don't have access to uint64_t, figure out if the compiler's unsigned long long type is large enough, it's often 64 bits which is what you need. If that fails, you might need to roll your own high-precision integer, since you only need e.g. a pair of 32-bit numbers it shouldn't be too hard.

why pointer variable not showing 100 digits?

aim: i had a requirement for accuracy i need 100 digits to be displayed or atleast 50 digits
try 1: first i had used integer variable then it displayed only 10 digits
try 2: with the help of my friend i used pointers concept it successfully had input 50 to 100 digits but pointer variable display only 10 digits
the program i had written was
#include <stdio.h>
#include <string.h>
main()
{
int *p;
p=(int*)malloc(100*sizeof(int));
*p=1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890;
printf("%d",*p);
}
on executing the above procedure i'm getting a garbage value
thanks in advance
You need to use a bignum (arbitrary precision big numbers) library, since native int or long have a precision limited by the C implementation - ie the hardware (often 32 or 64 bits; see also <stdint.h> header and int32_t & int64_t types). I suggest using GMPlib; you need to be fluent in C to use such libraries. Read documentation of GMLib.
Don't try to code bignumber arithmetic yourself. You'll use inefficient algorithms. Efficient algorithms for bignums are difficult to understand and to invent. You can still get a PhD on that. So use some existing bignum library.
So you might code something like the following to multiply your bignum by 137 and print the result
mpz_t bign;
mpz_t bigr;
// initialize bign from a literal string
mpz_init_set_str (bign,
"12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890",
10);
// initialize bigr
mpz_init(bigr);
/// compute bigr = bign * 137 (137 is a long, not a bignum)
mpz_mul_si(bigr, bign, 137L);
/// print bigr on stdout in base 10
mpz_out_str (stdout, 10, bigr);
/// clear all the numbers
mpz_clear(bign);
mpz_clear(bigr);
On a Linux system with GMP installed, you could compile such a code (in yoursource.c) using:
gcc -Wall -Wextra -g yoursource.c -lgmp -o yourprog
On other systems you might need some -I and -L arguments to gcc. When you have debugged your program, ask the compiler to optimize it with -O2
Notice that some languages (Common Lisp, Scheme, Python) have built-in bignums.
BTW, your main function is incorrectly defined. It should be defined as int main(int argc, char**argv) ...
To answer the first part, a single signed integer (assuming 32 bits) can take values between -2,147,483,648 and +2,147,483,647
This is where your ten digits comes from.
Depending on your compiler, you may have unsigned long long available (64 bits) but that still only offers you a maximum or 0..18,446,744,073,709,551,615 (20 digits)
To handle 100-digit numbers will require some jiggery-pokery!
int * p = malloc(100*sizeof(int));
Allocates memory for an array of 100 int.
*p= ....
In fact is the same as
p[0]=...
So this
*p=1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890;
assigns to an int.
An int may hold not more then a 32 bits (less on some platforms). The largest 32bit (positive) integer is 2147483647.
C is a language close to the hardware. So you need to understand the storage capabilities and limitations of its data types.
An int on a PC is only able to store 32 bit or 64 bit values, depending on your hardware and OS version.
Yes, you can implement routines for handling larger value, and using a linked list of digits is one way do it.
You can't store such a long digit in an int variable or a pointer which is pointing to type int.
If int is of 32 bit, the range is [−2147483647,+2147483647]. C data types
To store the large value you can use a char pointer and initialized it with the string constant.
For example:
#include <stdio.h>
#include <stdlib.h>
main()
{
char *p = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
printf("%s\n",p);
}

A small program for understanding unions in C [duplicate]

Suppose I define a union like this:
#include <stdio.h>
int main() {
union u {
int i;
float f;
};
union u tst;
tst.f = 23.45;
printf("%d\n", tst.i);
return 0;
}
Can somebody tell me what the memory where tst is stored will look like?
I am trying to understand the output 1102813594 that this program produces.
It depends on the implementation (compiler, OS, etc.) but you can use the debugger to actually see the memory contents if you want.
For example, in my MSVC 2008:
0x00415748 9a 99 bb 41
is the memory contents. Read from LSB on the left side (Intel, little-endian machine), this is 0x41bb999a or indeed 1102813594.
Generally, however, the integer and float are stored in the same bytes. Depending on how you access the union, you get the integer or floating point interpretation of those bytes. The size of the memory space, again, depends on the implementation, although it's usually the largest of its constituents aligned to some fixed boundary.
Why is the value such as it is in your (or mine) case? You should read about floating-point number representation for that (look up ieee 754)
The result is depends on the compiler implementation, But for most x86 compilers, float and int will be the same size. Wikipedia has a pretty good diagram of the layout of a 32 bit float http://en.wikipedia.org/wiki/Single_precision_floating-point_format, that can help to explain 1102813594.
If you print out the int as a hex value, it will be easier to figure out.
printf("%x\n", tst.i);
With a union, both variables are stored starting at the same memory location. A float is stored in an IEEE format (can't remember the standard number, you can look that up[edit: as pointed out by others, IEEE 754]). But, it will be a two's complement normalized (mantissa is always between 0 and 10, exponent can be anything) floating point number.
you are taking the first 4 bytes of that number (again, you can look up what bits go where in the 16 or 32 bits that a float takes up, can't remember). So it basically means nothing and it isn't useful as an int. That is, unless you know why you would want to do something like that, but usually, a float and int combo isn't very useful.
And, no, I don't think it is implementation defined. I believe that the standard dictates what format a float is in.
In union, members will be share the same memory. so that we can get the float value as integer value.
Floating number format will be different from integer storage. so that we can understand the difference using the union.
For Ex:
If I store the 12 integer value in ( 32 bits ). we can get this 12 value as floating point format.
It will stored as signed(1 bit), exponent(8 bits) and significant precision(23 bits).
I wrote a little program that shows what happens when you preserve the bit pattern of a 32-bit float into a 32-bit integer. It gives you the exact same output you are experiencing:
#include <iostream>
int main()
{
float f = 23.45;
int x = *reinterpret_cast<int*>(&f);
std::cout << x; // 1102813594
}

How to convert a decimal ascii string to integer array in C?

I have written a program that works with IPv6 addresses, and I needed code that converts a four-integer array to decimal string that represented number of IPv6 addresses[1]. Now I ran into the situation when I need to do reverse: convert possibly large number (that do not fits into uint32_t or uint64_t, so atol() or strtol() are helpless here) represented as a single string to four-integer or byte (uint8_t) array (I converted function from [1] from 4-int to variable-uint8_t).
Is there any way to do that?
[1] How to convert a 128-bit integer to a decimal ascii string in C?
Thanks. This is my first question here, so sorry for bad English if any.
This is the kind of situation when using a library is recommended.
Using GMP, you can do these conversions (gmp.c):
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
int main(int argc, char *argv)
{
// From string
char *s ="199999999999999999999999999999999999999";
mpz_t i;
// To big number, using GMP
// 10 here means base 10.
mpz_init_set_str(i, s, 10);
// Just to test if s is 128 bits long
printf("%s can be represented with %d digits in base 2\n",s, mpz_sizeinbase(i, 2));
// Then you can print it in hex
gmp_printf("%#32ZX\n", i);
// Or convert it back to int[4]
unsigned int a[4];
mpz_export(&a, NULL, 1, 4, 0, 0, i);
for(int x=0;x<4;x++)
printf("%X\n", a[x]);
mpz_clear(i);
return 0;
}
Output:
199999999999999999999999999999999999999 can be represented with 128 digits in base 2
0X96769950B50D88F41314447FFFFFFFFF
96769950
B50D88F4
1314447F
FFFFFFFF
I tested this code on a 32 bit Linux system. Please pay attention to different int sizes and endianess on different platforms.
You probably want the result in big endian, if so, just change mz_export to:
mpz_export(&a, NULL, 1, 4, 1, 0, i);
To compile the example, don't forget to install gmp and to add -lgmp -std=c99 on gcc command line parameters.
On Ubuntu, you can install gmp with:
sudo apt-get install libgmp-dev
And compile the example, gmp.c:
gcc gmp.c -o gmp -lgmp -std=c99
This code can be a good start for your conversions. You can also initialize i to be a fixed 128 bit number (using init functions of GMP), just in case your big number starts with zeros.

Storing a large number in C

I have the following code where I have an array. I add a large number to that array, but when printing it, it shows a smaller, incorrect value. Why is that, and is there a way to fix this?
int x[10];
x[0] = 252121521121;
printf(" %i " , x[0]); //prints short wrong value
Your number requires 38 bit. If your platform's int isn't that big (and there's no reason it should be), the number simply won't fit. (In fact, even the int literal should already have triggered a compiler warning, supposing that this is C or C++.)
You could always use a data type of guaranteed size, like an int64 or something like that, depending on your language and platform. Probably no need for arbitrary-precision libraries here.
In C, include <stdint.h> and use int64_t, or just use long long int, and make sure you initialize it from a long long integer literal, e.g. 252121521121LL. (Long longs are only officially part of the most recent language standards, I might add.)
(Edit: long long int is guaranteed to be at least 64 bit, so it should be a good choice.)
An int, on most systems, is 32 bits. That's enough to store a number of about 2 billion signed, or 4 billion unsigned. To store larger numbers you need a larger form of int. (Unfortunately, on some systems a long int is the same as an int -- good ol' standardization -- so you need to go to a long long int. Better if you can find a typedef in your library such as int64_t.)
If you only have the problem with this particular number, then just use a long long int as suggested in previous answers.
Otherwise, for even larger numbers (>1E19 for signed numbers), you might want to switch to a large number library or code yourself this kind of data type. You basically need to store each digit of your number in an array (or linked list) and manually code basic operations you need on them : adding, subtracting, multiplying etc.
Some libraries include
https://mattmccutchen.net/bigint/
or GMP.
Well, your number just seems to exceed the maximum value a 32bit integer can hold..

Resources