Say that I have
#define A 23.9318;
#define B 0.330043;
#define C 5.220628;
I want to do
const unsigned result = (unsigned)(0x01000000 * ( A * B / C )); // unsigned is 32 bit
What I hope for is to have result with fixed decimal representation of the floating point calculations.
I cannot pre combine A,B,C together as their definition is not part of my code and I need
it to work if they are changed.
No, the standard C preprocessor operations do not perform floating-point arithmetic.
A C implementation is permitted, but not required, by the C standard to perform these operations at compile-time.
Illustrates that although not required, some C implementations do include compile-time computations of floating point...
The following code was compiled using a C99 implementation and produced the indicated results (commented value in main():
#include <ansi_c.h>
#define A 23.9318
#define B 0.330043
#define C 5.220628
#define result A*B/C //1.512945007267325
const unsigned resultB = (unsigned)result*(0x01000000);
int main(void)
{
resultB; //24394701
return 0;
}
Related
For checking whether two numbers have the same sign:
#define same_sign(a,b) ((a)*(b)>=0)
but this can also be done with:
#define INTEL_REVERSED//example define specifying whether variables are stored in memory in reverse
#ifdef INTEL_REVERSED
#define same_sign(a,b) ((~(*((char*)&a+sizeof(a)-1)^*((char*)&b+sizeof(b)-1))&0x80)>>7)
#else
#define same_sign(a,b) ((~(*(char*)&a^*(char*)&b)&0x80)>>7)
#endif
Multiplication has time complexity of in between O(n log n) and O(n^2) (when the number is bigger than 4 bytes), while logic always takes the same amount of time. When would the second implementation work faster than the first? Also, I understand that the second one doesn't work on expressions, but only on variables and that for the second one it's possible to put any any data-type, not just integral ones and that first requires integral types(double and float included).
Edit: I've found an error in the first code(I'm suprised that nobody pointed this out): instead of >, there should have been a >=.
The multiplication method is as slow as you might expect, but it is risky: it has undefined behavior if there is an overflow, which is not unlikely for a multiplication, eg: same_sign(-50000, -50000).
Instead of the complicated, system specific macro posted, you can use this simple method:
static inline int same_sign(int a, int b) { return (a ^ b) >= 0; }
If you really want a macro to handle integer types int, long and long long with a single expression, use this:
#define same_sign(a, b) (((a) ^ (b)) >= 0)
The above solutions work for two's complement representation of signed integers. Other representations will have false positives, but you are unlikely to encounter such oddities and support for these will be removed from the next version of the C Standard.
For floating point values, you should use this instead:
#include <math.h>
#define same_sign(a, b) (signbit(a) == signbit(b))
Note that you can write a macro that will work for all non complex number types and should compile to efficient code:
#define same_sign(a, b) (((a) < 0) == ((b) < 0))
This question already has answers here:
Type of #define variables
(7 answers)
Closed 3 years ago.
When using the #define command in C, what is the maximum or minimum amount the variable can be? For example, is
#define INT_MIN (pow(-2,31))
#define INT_MAX (pow(2,31))
an acceptable definition? I suppose a better way to ask is what is the datatype of the defined value?
#define performs token substitution. If you don't know what tokens are, you can think of this as text substitution on complete words, much like your editor's "search and replace" function could do. Therefore,
#define FOO 123456789123456789123456789123456789123456789
is perfectly valid so far — that just means that the preprocessor will replace every instance of FOO with that long number. It would also be perfectly legal (as far as preprocessing goes) to do
#define FOO this is some text that does not make sense
because the preprocessor doesn't know anything about C, and just replaces FOO with whatever it is defined as.
But this is not the answer you're probably looking for.
After the preprocessor has replaced the macro, the compiler will have to compile whatever was left in its place. And compilers will almost certainly be unable to compile either example I posted here and error out.
Integer constants can be as large as the largest integer type defined by your compiler, which is equivalent to uintmax_t (defined in <stdint.h>). For instance, if this type is 64 bits wide (very common case), the maximum valid integer constant is 18446744073709551615, i.e., 2 to the power of 64 minus 1.
This is independent of how this constant is written or constructed — whether it is done via a #define, written directly in the code, written in hexadecimal, it doesn't matter. The limit is the same, because it is given by the compiler, and the compiler runs after preprocessing is finished.
EDIT: as pointed out by #chux in comments, in recent versions of C (starting with C99), decimal constants will be signed by default unless they carry a suffix indicating otherwise (such as U/u, or a combined type/signedness suffix like ULL). In this case, the maximum valid unsuffixed constant would be whatever fits in an intmax_t value (typically half the max of uintmax_t rounded down); constants with unsigned suffixes can grow as large as an uintmax_t value can. (Note that C integer constants, signed or not, are never negative.)
#define INT_MIN (pow(-2,31)) is not acceptable, as it forms a maximum of the wrong type.
pow() returns a double.
Consider this: INT_MIN % 2 leads to invalid code, as % cannot be done on a double.
Your definition is ill-advised for a number of reasons:
These macro names are used in the standard library header limits.h where they are correctly defined for the toolchain's target platform.
Macros are not part of the C language proper; rather they cause replacement text to be inserted into the code for evaluation by the compiler; as such your definition will cause the functionpow() to be called everywhere these macros are used - evaluated at run-time (repeatedly) rather then being a compile-time constant.
The maximum value of a 32 bit two's complement integer is not 231 but 231 - 1.
The pow() function returns a double not an integer - your macro expressions therefore have type double.
Your macros assume the integer size of the platform to be 32 bit, which need not be the case - the definitions are not portable. This is possibly true also of those in , but there the entire library is platform specific, and you'd use a different library/toolchain with each platform.
If you must (and you really shouldn't) define your own macros for this purpose, you should:
define them using distinct macro names,
without assumptions regarding the target platform integer width,
use a constant-expression,
use an expression having int type.
For example:
#define PLATFORM_INDEPENDENT_INT_MAX ((int)(~0u >> 1u))
#define PLATFORM_INDEPENDENT_INT_MIN ((int)~(~0u >> 1u))
Using these the following code:
#include <stdio.h>
#include <limits.h>
#define PLATFORM_INDEPENDENT_INT_MAX ((int)(~0u >> 1u))
#define PLATFORM_INDEPENDENT_INT_MIN ((int)~(~0u >> 1u))
int main()
{
printf( "Standard: %d\t%d\n", INT_MIN, INT_MAX);
printf( "Mine: %d\t%d\n", PLATFORM_INDEPENDENT_INT_MIN, PLATFORM_INDEPENDENT_INT_MAX);
return 0;
}
Outputs:
Standard: -2147483648 2147483647
Mine: -2147483648 2147483647
I am developing a library of special-purpose math functions in C. I need to provide a capability for the library to handle both single-precision and double-precision. The important point here is that the "single" functions should use ONLY "single" arithmetic internally (resp. for the "double" functions).
As an illustration, take a look at LAPACK (Fortran), which provides two versions of each of its function (SINGLE and DOUBLE). Also the C math library (example, expf and exp).
To clarify, I want to support something similar to the following (contrived) example:
float MyFloatFunc(float x) {
return expf(-2.0f * x)*logf(2.75f*x);
}
double MyDoubleFunc(double x) {
return exp(-2.0 * x)*log(2.75*x);
}
I've thought about the following approaches:
Using macros for the function name. This still requires two separate source codebases:
#ifdef USE_FLOAT
#define MYFUNC MyFloatFunc
#else
#define MYFUNC MyDoubleFunc
#endif
Using macros for the floating point types. This allows me to share the codebase across the two different versions:
#ifdef USE_FLOAT
#define NUMBER float
#else
#define NUMBER double
#endif
Just developing two separate libraries, and forgetting about trying to save headaches.
Does anyone have a recommendation or additional suggestions?
For polynomial approximations, interpolations, and other inherently approximative math functions, you cannot share code between a double-precision and a single-precision implementation without either wasting time in the single-precision version or being more approximative than necessary in the double-precision one.
Nevertheless, if you go the route of the single codebase, the following should work for constants and standard library functions:
#ifdef USE_FLOAT
#define C(x) x##f
#else
#define C(x) x
#endif
... C(2.0) ... C(sin) ...
(Partially inspired by Pascal Cuoq's answer)
If you want one library with float and double versions of everything, you could use recursive #includes in combination with macros. It doesn't result in the clearest of code, but it does let you use the same code for both versions, and the obfuscation is thin enough it's probably manageable:
mylib.h:
#ifndef MYLIB_H_GUARD
#ifdef MYLIB_H_PASS2
#define MYLIB_H_GUARD 1
#undef C
#undef FLT
#define C(X) X
#define FLT double
#else
/* any #include's needed in the header go here */
#undef C
#undef FLT
#define C(X) X##f
#define FLT float
#endif
/* All the dual-version stuff goes here */
FLT C(MyFunc)(FLT x);
#ifndef MYLIB_H_PASS2
/* prepare 2nd pass (for 'double' version) */
#define MYLIB_H_PASS2 1
#include "mylib.h"
#endif
#endif /* guard */
mylib.c:
#ifdef MYLIB_C_PASS2
#undef C
#undef FLT
#define C(X) X
#define FLT double
#else
#include "mylib.h"
/* other #include's */
#undef C
#undef FLT
#define C(X) X##f
#define FLT float
#endif
/* All the dual-version stuff goes here */
FLT C(MyFunc)(FLT x)
{
return C(exp)(C(-2.0) * x) * C(log)(C(2.75) * x);
}
#ifndef MYLIB_C_PASS2
/* prepare 2nd pass (for 'double' version) */
#define MYLIB_C_PASS2 1
#include "mylib.c"
#endif
Each file #includes itself one additional time, using different macro definitions on the second pass, to generate two versions of the code that uses the macros.
Some people may object to this approach, though.
The big question for you will be:
Is it easier to maintain two separate unobfuscated source trees, or one obfuscated one?
If you have the proposed common coding, you will have to write the code in a stilted fashion, being very careful not to write any undecorated constants or non-macro function calls (or function bodies).
If you have separate source code trees, the code will be simpler to maintain in that each tree will look like normal (non-obfuscated) C code, but if there is a bug in YourFunctionA in the 'float' version, will you always remember to make the matching change in the 'double' version.
I think this depends on the complexity and volatility of the functions. My suspicion is that once written and debugged the first time, there will seldom be a need to go back to it. This actually means it doesn't matter much which mechanism you use - both will be workable. If the function bodies are somewhat volatile, or the list of functions is volatile, then the single code base may be easier overall. If everything is very stable, the clarity of the two separate code bases may make that preferable. But it is very subjective.
I'd probably go with a single code base and wall-to-wall macros. But I'm not certain that's best, and the other way has its advantages too.
The <tgmath.h> header, standardized in C 1999, provides type-generic calls to the routines in <math.h> and <complex.h>. After you include <tgmath.h>;, the source text sin(x) will call sinl if x is long double, sin if x is double, and sinf if x is float.
You will still need to conditionalize your constants, so that you use 3.1 or 3.1f as appropriate. There are a variety of syntactic techniques for this, depending on your needs and what appears more aesthetic to you. For constants that are exactly represented in float precision, you can simply use the float form. E.g., y = .5f * x will automatically convert .5f to double if x is double. However, sin(.5f) will produce sinf(.5f), which is less accurate than sin(.5).
You might be able to reduce the conditionalization to a single clear definition:
#if defined USE_FLOAT
typedef float Float;
#else
typedef double Float;
#endif
Then you can use constants in ways like this:
const Float pi = 3.14159265358979323846233;
Float y = sin(pi*x);
Float z = (Float) 2.71828182844 * x;
That might not be completely satisfactory because there are rare cases where a numeral converted to double and then to float is less accurate than a numeral converted directly to float. So you may be better off with a macro described above, where C(numeral) appends a suffix to the numeral if necessary.
i want to use the sqrt implementation of fdlibm.
This implementation defines (according to the endianess) some macros for accessing the lower/upper 32-bit of a double) in the following way (here: only the little-endian-version):
#define __HI(x) *(1+(int*)&x)
#define __LO(x) *(int*)&x
#define __HIp(x) *(1+(int*)x)
#define __LOp(x) *(int*)x
The readme of flibm is saying the following (a little bit shortened)
Each double precision floating-point number must be in IEEE 754
double format, and that each number can be retrieved as two 32-bit
integers through the using of pointer bashing as in the example
below:
Example: let y = 2.0
double fp number y: 2.0
IEEE double format: 0x4000000000000000
Referencing y as two integers:
*(int*)&y,*(1+(int*)&y) = {0x40000000,0x0} (on sparc)
{0x0,0x40000000} (on 386)
Note: Four macros are defined in fdlibm.h to handle this kind of
retrieving:
__HI(x) the high part of a double x
(sign,exponent,the first 21 significant bits)
__LO(x) the least 32 significant bits of x
__HIp(x) same as __HI except that the argument is a pointer
to a double
__LOp(x) same as __LO except that the argument is a pointer
to a double
If the behavior of pointer bashing is undefined, one may hack on the
macro in fdlibm.h.
I want to use this implementation and these macros with the cbmc model checker, which should be conformable with ansi-c.
I don't know exactly whats wrong, but the following example shows that these macros aren't working (little-endian was chosen, 32-bit machine-word was chosen):
temp=24376533834232348.000000l (0100001101010101101001101001010100000100000000101101110010000111)
high=0 (00000000000000000000000000000000)
low=67296391 (00000100000000101101110010000111)
Both seem to be wrong. High seems to be empty for every value of temp.
Any new ideas for accessing the both 32-words with ansi-c?
UPDATE: Thanks for all your answers and comments. All of your proposals worked for me. For the moment i decided to use "R.."s version and marked this as favorite answer because it seems to be the most robust in my tool regarding endianness.
Why not use an union?
union {
double value;
struct {
int upper;
int lower;
} words;
} converter;
converter.value = 1.2345;
printf("%d",converter.words.upper);
(Note that the behaviour code is implementation-dependent and relies on internal representation and specific data sizes)
On top of that, if you make that struct contain bitfields, you can access the individual floating-point parts (sign, exponent and mantissa) separately:
union {
double value;
struct {
int upper;
int lower;
} words;
struct {
long long mantissa : 52; // not 2C!
int exponent : 11; // not 2C!
int sign : 1;
};
} converter;
Casting pointers like you're doing violates the aliasing rules of the C language (pointers of different types may be assumed by the compiler not to point to the same data, except in certain very restricted cases). A better approach might be:
#define REP(x) ((union { double v; uint64_t r; }){ x }).r
#define HI(x) (uint32_t)(REP(x) >> 32)
#define LO(x) (uint32_t)(REP(x))
Note that this also fixed the endian dependency (assuming the floating point and integer endianness are the same) and the illegal _-prefix on the macro names.
An even better way might be not breaking it into high/low portions at all, and using the uint64_t representation REP(x) directly.
From a standards perspective, this use of unions is a little bit suspect, but better than the pointer casts. Using a cast to unsigned char * and accessing the data byte-by-byte would be better in some ways, but worse in that you have to worry about endian considerations, and probably a lot slower..
I would suggest taking a look at the disassembly to see exactly why the existing "pointer-bashing" method does not work. In its absence, you might use something more traditional like a binary shift (if you're on a 64-bit system).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
A riddle (in C)
I have a couple of questions regarding the following snippet:
#include<stdio.h>
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};
int main()
{
int d;
for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
printf("%d\n",array[d+1]);
return 0;
}
Here the output of the code does not print the array elements as expected. But when I add a typecast of (int) the the macro definition of ELEMENTS as
#define TOTAL_ELEMENTS (int) (sizeof(array) / sizeof(array[0]))
It displays all array elements as expected.
How does this typecast work?
Based on this I have few questions:
Does it mean if I have some macro definition as:
#define AA (-64)
by default in C, all constants defined as macros are equivalent to signed int.
If yes, then
But if I have to forcibly make some constant defined in a macro behave as an unsigned int is there any constant suffix than I can use (I tried UL, UD neither worked)?
How can I define a constant in a macro definition to behave as unsigned int?
Look at this line:
for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
In the first iteration, you are checking whether
-1 <= (TOTAL_ELEMENTS-2)
The operator size_of returns unsigned value and the check fails (-1 signed = 0xFFFFFFFF unsigned on 32bit machines).
A simple change in the loop fixes the problem:
for(d=0;d <= (TOTAL_ELEMENTS-1);d++)
printf("%d\n",array[d]);
To answer your other questions: C macros are expanded text-wise, there is no notion of types. The C compiler sees your loop as this:
for(d=-1;d <= ((sizeof(array) / sizeof(array[0]))-2);d++)
If you want to define an unsigned constant in a macro, use the usual suffix (u for unsigned, ul for unsigned long).
sizeof returns the number of bytes in unsigned format. That's why you need the cast.
See more here.
Regarding your question about
#define AA (-64)
See Macro definition and expansion in the C preprocessor:
Object-like macros were conventionally used as part of good programming practice to create symbolic names for constants, e.g.
#define PI 3.14159
... instead of hard-coding those numbers throughout one's code. However, both C and C++ provide the const directive, which provides another way to avoid hard-coding constants throughout the code.
Constants defined as macros have no associated type. Use const where possible.
Answering just one of your sub-questions:
To "define a constant in a macro" (this is a bit sloppy, you're not defining a "constant", merely doing some text-replacement trickery) that is unsigned, you should use the 'u' suffix:
#define UNSIGNED_FORTYTWO 42u
This will insert an unsigned int literal wherever you type UNSIGNED_FORTYTWO.
Likewise, you often see (in <math.h> for instance) suffices used to set the exact floating-point type:
#define FLOAT_PI 3.14f
This inserts a float (i.e. "single precision") floating-point literal wherever you type FLOAT_PI in the code.