-DBL_MAX in ANSI C, which is defined in float.h.
-DBL_MAX in ANSI C, which is defined in float.h.
Floating point numbers (IEEE 754) are symmetrical, so if you can represent the greatest value (DBL_MAX or numeric_limits<double>::max()), just prepend a minus sign.
And then is the cool way:
double f;
(*((uint64_t*)&f))= ~(1LL<<52);
c - Minimum of two floating-point numbers - Code Review Stack Exchange
Why don't float/double have a max & min value like 'int' or 'char'?
Just something I noticed with DOUBLE_MIN - GameDev.net Forums
MIN and MAX in C - Stack Overflow
Versatility
The pointer version is less versatile.
If the two values come from expressions like in min_value(x + 13, 2 * y), you can't use the pointer version, as neither x + 13 nor 2 * y exist as pointable memory locations, only as temporary values.
Surprises
The pointer version might give surprising results in the long run.
If now first is lower than second, the function will return a pointer to first. If you later change the content of the first variable, the value of the result changes as well.
If first and second are local variables declared inside a function foo(), and you happen to return the pointer_min_value() result (the pointer), then, after leaving foo(), the variables no longer exist, and your result points to garbage memory.
Some beautifying
I think first < second ? first : second is a tiny bit more readable. First comes first.
Double problems
Floating points are tricky. What will happen if one of doubles will be NaN? Of course, you can always say that the function assumes both values are valid, but you should consider this too.
Pointer problems
Pointers are also tricky. pointer_min_value(NULL, NULL) will cause UB. Once again, adding a comment "no NULLs allowed" is ok - but neglecting this possibility isn't.
Making sure the values, passed by pointers, won't change
You can add const modifier to arguments and returning value to do this, if you mean this.
Performance considerations
Passing a huge argument by value can be a bad idea; but doubles are only 8 bytes - like pointers on 86x64 architecture; pointers on 86x32 are 4 bytes, so you can save 8 bytes of stack space with pointer_min_value. But who cares with modern RAM sizes?
On the other hand, dereferencing pointers isn't free, so calc_min_value will be a bit faster, but who cares with modern CPU/RAM speeds and cache sizes?
Chief difference
The only thing pointer_min_value does that calc_min_value doesn't - it returns a pointer. Why is this important? Because you can change the returned value!
*pointer_min_value(&first, &second) = 0.0;
changes lesser one to 0.0. That's the greatest difference.
source: https://www.tutorialspoint.com/cplusplus/cpp_data_types.htm#
There's no data shown for the limits floats and doubles have.
However, 'int' is -2147483648 to 2147483647 and 'char' is 0 to 255
Where are
MINandMAXdefined in C, if at all?
They aren't.
What is the best way to implement these, as generically and type safe as possible (compiler extensions/builtins for mainstream compilers preferred).
As functions. I wouldn't use macros like #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)), especially if you plan to deploy your code. Either write your own, use something like standard fmax or fmin, or fix the macro using GCC's typeof (you get typesafety bonus too) in a GCC statement expression:
#define max(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a > _b ? _a : _b; })
Everyone says "oh I know about double evaluation, it's no problem" and a few months down the road, you'll be debugging the silliest problems for hours on end.
Note the use of __typeof__ instead of typeof:
If you are writing a header file that must work when included in ISO C programs, write
__typeof__instead oftypeof.
It's also provided in the GNU libc (Linux) and FreeBSD versions of sys/param.h, and has the definition provided by dreamlax.
On Debian:
$ uname -sr
Linux 2.6.11
$ cat /etc/debian_version
5.0.2
$ egrep 'MIN\(|MAX\(' /usr/include/sys/param.h
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
$ head -n 2 /usr/include/sys/param.h | grep GNU
This file is part of the GNU C Library.
On FreeBSD:
$ uname -sr
FreeBSD 5.5-STABLE
$ egrep 'MIN\(|MAX\(' /usr/include/sys/param.h
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
The source repositories are here:
- GNU C Library
- FreeBSD
Alright. Using what I learned from here (thanks everyone) and the other parts of the web I wrote a neat little summary of the two just in case I run into another issue like this.
In C++ there are two ways to represent/store decimal values.
Floats and Doubles
A float can store values from:
- -340282346638528859811704183484516925440.0000000000000000 Float lowest
- 340282346638528859811704183484516925440.0000000000000000 Float max
A double can store values from:
-179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0000000000000000 Double lowest
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0000000000000000 Double max
Float's precision allows it to store a value of up to 9 digits (7 real digits, +2 from decimal to binary conversion)
Double, like the name suggests can store twice as much precision as a float. It can store up to 17 digits. (15 real digits, +2 from decimal to binary conversion)
e.g.
float x = 1.426;
double y = 8.739437;
Decimals & Math
Due to a float being able to carry 7 real decimals, and a double being able to carry 15 real decimals, to print them out when performing calculations a proper method must be used.
e.g
include
typedef std::numeric_limits<double> dbl;
cout.precision(dbl::max_digits10-2); // sets the precision to the *proper* amount of digits.
cout << dbl::max_digits10 <<endl; // prints 17.
double x = 12345678.312;
double a = 12345678.244;
// these calculations won't perform correctly be printed correctly without setting the precision.
cout << endl << x+a <<endl;
example 2:
typedef std::numeric_limits< float> flt;
cout.precision(flt::max_digits10-2);
cout << flt::max_digits10 <<endl;
float x = 54.122111;
float a = 11.323111;
cout << endl << x+a <<endl; /* without setting precison this outputs a different value, as well as making sure we're *limited* to 7 digits. If we were to enter another digit before the decimal point, the digits on the right would be one less, as there can only be 7. Doubles work in the same way */
Roughly how accurate is this description? Can it be used as a standard when confused?
The std::numerics_limits class in the <limits> header provides information about the characteristics of numeric types.
For a floating-point type T, here are the greatest and least values representable in the type, in various senses of “greatest” and “least.” I also include the values for the common IEEE 754 64-bit binary type, which is called double in this answer. These are in decreasing order:
std::numeric_limits<T>::infinity()is the largest representable value, ifTsupports infinity. It is, of course, infinity. Whether the typeTsupports infinity is indicated bystd::numeric_limits<T>::has_infinity.std::numeric_limits<T>::max()is the largest finite value. Fordouble, this is 21024−2971, approximately 1.79769•10308.std::numeric_limits<T>::min()is the smallest positive normal value. Floating-point formats often have an interval where the exponent cannot get any smaller, but the significand (fraction portion of the number) is allowed to get smaller until it reaches zero. This comes at the expense of precision but has some desirable mathematical-computing properties.min()is the point where this precision loss starts. Fordouble, this is 2−1022, approximately 2.22507•10−308.std::numeric_limits<T>::denorm_min()is the smallest positive value. In types which have subnormal values, it is subnormal. Otherwise, it equalsstd::numeric_limits<T>::min(). Fordouble, this is 2−1074, approximately 4.94066•10−324.std::numeric_limits<T>::lowest()is the least finite value. It is usually a negative number large in magnitude. Fordouble, this is −(21024−2971), approximately −1.79769•10308.If
std::numeric_limits<T>::has_infinityandstd::numeric_limits<T>::is_signedare true, then-std::numeric_limits<T>::infinity()is the least value. It is, of course, negative infinity.
Another characteristic you may be interested in is:
std::numeric_limits<T>::digits10is the greatest number of decimal digits such that converting any decimal number with that many digits toTand then converting back to the same number of decimal digits will yield the original number. Fordouble, this is 15.
DBL_MAX is defined in <float.h>. Its availability in <limits.h> on unix is what is marked as "(LEGACY)".
(linking to the unix standard even though you have no unix tag since that's probably where you found the "LEGACY" notation, but much of what is shown there for float.h is also in the C standard back to C89)
You get the integer limits in <limits.h> or <climits>. Floating point characteristics are defined in <float.h> for C. In C++, the preferred version is usually std::numeric_limits<double>::max() (for which you #include <limits>).
As to your original question, if you want a larger integer type than long, you should probably consider long long. This isn't officially included in C++98 or C++03, but is part of C99 and C++11, so all reasonably current compilers support it.