The ranges are actually –infinity to +infinity.
The largest finite float is 340282346638528859811704183484516925440. This is 2128–2128–24.
The largest finite double is 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368. This is 21024–21024–53.
The ranges are actually –infinity to +infinity.
The largest finite float is 340282346638528859811704183484516925440. This is 2128–2128–24.
The largest finite double is 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368. This is 21024–21024–53.
The ranges are represented in "exponential format" for conciseness. For example, +1.7e+308 means 17 followed by 307 zeros:
1,700,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
So the exponential format is preferred for such large numbers. And the same goes for extremely small numbers.
Also, take a look at this reading by Jon Skeet.
float, double and long double ranges ? - C++ Forum
c - Calculate the range of double - Stack Overflow
c - To print Range of Double - Stack Overflow
What does it mean in C that data type "Double" is more "expensive" than data type "Float"
Can double be used to store large numbers in C?
How do I round a double value to the nearest integer in C?
How do you use double for scientific notation in C?
OP's approach works when calculations are done with wider precision than float in the first case and wider than double in the 2nd case.
In the first case, OP reports FLT_EVAL_METHOD == 0 so float calculations are done as float and double are done as double. Note that float step ... 1.0 + step is a double calculation.
The below code forces the calculation to double and so I can replicate OP's problem even with my FLT_EVEL_METHOD==2 (Use long double for internal calculations.)
volatile double d = 1.0;
volatile double last_d;
volatile double step_d = 9.0;
while(1) {
last_d = d;
d *= (1.0 + step_d);
while (d == INFINITY) {
step_d /= 2.0;
volatile double sum = 1.0 + step_d;
d = last_d * sum;
//d = last_d + step_d*last_d;
}
if (! (d > last_d) ) {
break;
}
}
diff : 1.995840e+292
The expected value? : no
Instead OP should use the following which does not form the inexact sum of 1.0 + step_d when step_d is small, rather it forms the exact product of step_d*last_d. The 2nd form results in a more accurate calculation for the new d, by providing an additional bit of calculation precision in d. Higher precision FP is not needed to employ OP's approach.
d = last_d + step_d*last_d;
diff : 0x0p+0 0.000000e+00
The expected value? : yes
The expressions with the literals n.0 are all double precision floating point types. That allows the assignment to f to be calculated using a higher precision intermediate value.
It's this effect that allows the algorithm to converge in the float case.
With strict double precision floating point such convergence is not possible.
If you had used the f suffix on the literals in the float case then convergence would not occur there either.
A fix would be to use long double suffixes on the literals if your platform has a wider long double type.
The ranges for the signed integers are usually asymmetric — there's usually one more negative value than there are positive values.
The header <limits.h> defines the ranges for the integer types you specify.
ULONG_MAXULLONG_MAX
etc.
The header <float.h> defines the ranges for the floating point types:
DBL_MAXDBL_MIN
etc.
You must print the values using the correct format specifiers.
try to add "\n" to each print sentence:
printf("double%d to %d\n",-(d/2),(d/2)-1);
printf("longlongint%d to %d\n",-(lli/2),(lli/2)-1);
printf("unsigned longlongint%d\n",ulli-1);
printf("signed long longint%d to %d\n",-(slli/2),(slli/2)-1);
printf("unsigned int%d\n",ui-1 );
printf("unsignedlongint%d\n",uli-1);
UPDATE
As @Abhineet suggested, further information about buffered streaming could helps you, so reading this SO question may be interesting