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.
Related
I am trying to understand what is maxBit in the following and what it represents?
When I print min and max, I get numbers that make no sense to me.
Thank you.
#include <stdio.h>
#include <math.h>
int main() {
union {double a; size_t b;} u;
u.a = 12345;
size_t max = u.b;
u.a = 6;
size_t min = u.b;
int maxBit = floor(log(max-min) / log(2));
printf("%d",maxBit);
return 0;
}
This code appears to be using a horrible kludge. I am one of the more welcoming participants here regarding tolerating code that uses compiler extensions or other things beyond the C standard, but this code does simply unnecessary things for no apparent good purpose. It relies on size_t being 64 bits. It may be 64 bits in some specific C implementation this was written for, but that is not portable, and C implementations that use 64 bits are generally modern, and modern implementations ought to support the uint64_t of <stdint.h>, which would be an appropriate type for this. So better code would have used uint64_t.
Unless there is some quite surprising motivation for this and other issues in the code, it is low quality, bad code. Do not use it, and regard any code from the same source with skepticism.
That said, the code likely assumes the IEEE-754 binary64 is used for double, and max-min gives the difference between the representations of 12345 and 6. log(max-min) / log(2) finds the base-two-logarithm of max-min, and the integer portion of that will be the index of the highest bit that changed. For 12345, the exponent field is 1036. For 6, the exponent field is 1025. The difference is 11 (binary 1011), in which the first set bit is bit 3 of the exponent field. The field runs from bits 62 to 52 in the binary64 format, so bit 3 in the exponent field is bit 55 (52+3) in the whole 64 bits of the representation. So maxBit will be 55. However, there is no apparent significance to this. There is no great value in knowing that bit 55 is the highest bit set in the difference between the representations of 12345 and 6. I am familiar with a variety of IEEE-754 bit-twiddling hacks, and I do not recognize this. I expect nobody can tell you much more about this without context, such as where the code came from or how it is used.
From C17 document, 6.5.2.3 Structure and union members, footnote 97 :
If the member used to read the contents of a union object is not the
same as the member last used to store a value in the object, the
appropriate part of the object representation of the value is
reinterpreted as an object representation in the new type as described
in 6.2.6 (a process sometimes called “type punning”). This might be a
trap representation.
Therefore, when you store u.a = 12345 and then access size_t max = u.b, the bit patterns in the memory of u.a is reinterpreted as a size_t. Since, u.a is of double, it is represented in IEEE754 format.
The value stored in max and min are :
4668012349850910720 (0100000011001000000111001000000000000000000000000000000000000000-> IEEE754)
4618441417868443648 (0100000000011000000000000000000000000000000000000000000000000000-> IEEE754)
Then, max-min = 49570931982467072, then log(max-min)/log(2) = 55.460344, then floor(55.460344) = 55. This is reason for 55 as output.
PS: There are two types of IEEE754 format : Single precision (32) and Double precision (64). Please visit this website IEEE754 for more details.
I am new to embedded System. I would like to perform division between 2 unsigned 16 bit integer and display the answer(including the decimal values). I wonder how can I accomplish this in embedded-C. Float,double and unsigned long does not seem to work. I am using TI's TM4C launchpad.
uint8_t PPGMsg[5];
unsigned long PPG;
uint16_t IR_combined,RED_combined;
IR_combined = (PPGMsg[1]<< 8)|PPGMsg[2];
RED_combined = (PPGMsg[3]<< 8)|PPGMsg[4];
PPGMsg[0]=(RED_combined/IR_combined);
PPG=(RED_combined/IR_combined);
UARTprintf("IR_combined is: %d\n",IR_combined);
UARTprintf("RED_combined is: %d\n",RED_combined);
UARTprintf("PPG is: %d\n",PPGMsg[0]);
UARTprintf("long PPG is: %d\n",PPG);
For example when IR_combined is: 147 and RED_combined is: 1012, the PPG: 6.
However I would like the answer to be displayed as 6.88 instead.
For 2 decimals precision, you need to do (uint32_t)RED_combined*100/IR_combined. Then print the decimals as you would like them. Example:
#include <stdint.h>
#include <inttypes.h>
...
uint16_t RED_combined = 1012;
uint16_t IR_combined = 147;
uint16_t x = ((uint32_t)RED_combined*100u / IR_combined);
printf("%"PRIu16".%.2"PRIu16, x/100, x%100);
However, you also have lots of other problems/bugs:
IR_combined = (PPGMsg[1]<< 8)|PPGMsg[2]; is dangerous/buggy code. Since PPGMsg[1] is a small integer type, it gets promoted to int and you end up performing left shifts on a signed type. Similarly, the | invokes implicit promotion to signed type.
You must study Implicit type promotion rules.
(PPGMsg[3]<< 8)|PPGMsg[4]; Same bugs here.
PPGMsg[0]=(RED_combined/IR_combined); You store the result in a 8 bit variable that is too small to hold the result. I don't understand how this makes any sense. Are you trying to parse out the ls byte?
%d is used to print signed integers. UARTprintf("IR_combined is: %d\n",IR_combined); should be "IR_combined is: %"PRIu16 "\n",IR_combined. You find these format specifier macros in inttypes.h.
Same bug: UARTprintf("PPG is: %d\n",PPGMsg[0]);. Should be UARTprintf("PPG is: %"PRIu8 "\n",PPGMsg[0]);.
unsigned long is printed with %ld
Using the correct type matters, everywhere!
Also consider using a good compiler like gcc that does warn if you use the wrong format specifier. Or better yet, don't use printf-like functions at all - they are unsafe, slow and resource-heavy.
I am trying to declare a variable eLon with only 1 decimal place so that if I have the code:
elon=359.8
printf("eLon = %f\n",eLon);
and the output will be
eLon = 359.8
However the output I get is:
eLon = 359.7999999.
How I know that I could modify the printf so that it would be:
printf(eLon is %0.1f\n",eLon);
to get the desired result. This is NOT what I want to do. I just want the variable itself to only have one decimal place so that it equals 359.8 not 359.7999999, since this is critical for any computations I make. Do you know how I should modify my code to get the desired result. I tried doing what was suggested in other inquiries but it did not work for example the code:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main()
{
int endLonn;
float endLon,eLon;
endLon=359.8;
endLonn=359.8*10;
printf("%d is endLonn\n",endLonn);
eLon= endLonn / 10;
printf("elon is %f\n",eLon);
}
gives me the output:
elon is 359.00000000
Again this is also not what I am looking for. I want elon is 359.8. If you could help me tweak my code to get the desired result that would be great. Thank you for your time.
Instead of trying to cheat double or float and printf, you can use fixed point arithmetic. In the particular case of your example you will express variable in 0.1s of it's original value:
int in_10s;
in_10s=3598;
printf("My fixed point variable "
"represents %d.%01d value\n",
in_10s/10, abs(in_10s % 10));
In general case of n decimal places, the format to printf should be %d.%0nd, where n=log_10(scaling_factor^-1), and scaling factor is interpreted like here.
What you want is not a floating point number but a fixed point decimal, which is for example available in c# as decimal. c doesn't give you that. There are two "typical" approaches to roll your own:
Use a plain int and just have the decimal point at some position by convention. e.g. your value would be int elon=3598.
Use a struct with two ints, one for the whole number part and one for the amount of tenths (or hundredths, thousandths, ...)
In both cases, you will need to implement your own logic for output. The simple approach using a plain int at least lets you use basic arithmetics as usual.
You actually can't declare a variable to hold only one decimal figure. The only native types able to represent non-integer values are floating point types, on which any arithmetic operation which yield a value of the same nature. Floating point types cannot be limited to a fixed number of decimal figures.
In order to achieve what you are asking for, you have to either implement such behavior or use an existing implementation of what is called fixed-point airthmetic.
A pretty complete introduction can be found in Wikipedia's Fixed-Point arithmetic entry. At the end you will find a couple of libraries implementing it.
I just want the variable itself to only have one decimal place so that it equals 359.8 not 359.7999999,
You should use double:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main(void){
int endLonn;
double endLon,eLon;
endLon=359.8;
endLonn=359.8*10;
printf("%d is endLonn\n",endLonn);
eLon = endLonn / 10;
printf("elon is %.1lf\n%.1lf",eLon,endLon);
return 0;
}
Output:
3598 is endLonn
elon is 359.0
359.8
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);
}
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);
}