I saw some code and I am astonished to see a conditional statement.
I have tried running it but the loop becomes a infinite loop.
The full code is :
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int *n;
for (int i=0; i<5e7; i++)
n = new int;
delete n;
}
How does that even compile, and why does the loop become an infinite loop?
What are these type of conditional statements?
To represent floating constants the C++ Standard introduces floating literals (
2.14.4 Floating literals )
floating-literal:
fractional-constant exponent-partopt floating-suffixopt
digit-sequence exponent-part floating-suffixopt
fractional-constant:
digit-sequenceopt. digit-sequence
digit-sequence .
exponent-part:
e signopt digit-sequence
E signopt digit-sequence
sign: one of
+ -
digit-sequence:
digit
digit-sequence ’opt digit
floating-suffix: one of
f l F L
Thus 5e7 is a floating literal. You can output it on console for example the following way
std::cout << std::fixed << std::setprecision( 0 ) << 5e7 << std::endl;
and the output will be
50000000
According to the rules of the usual arithmetic conversions in this condition
i < 5e7
variable i is converted to type double (because the floating literal has type double)and compared with the floating literal. As soon as i will be greater than or equal to the floating literal the loop stops its iterations. It can occur in case when maximum value of type int is not less than the value of the floating literal.
You can check the maximum value of an object of type int the following way
#include <limits>
//...
std::cout << std::numeric_limits<int>::max() << std::endl;
Where I run this code I got the following result
2147483647
Thus for these values the loop can not be infinite. However maybe in your system the maximum value of int is less than the value of the floating literal. In this case the loop indeed will be infinite.
Related
I know that we shouldn't use floating points in the loops. But could someone explain it to me what happens when we have a loop and we add a small number to a large number until we reach a certain value that allows the loop to terminate?
I guess it might cause potential errors. But apart from that?
What would it look like with a single-precision (float) and double-precision (double) floating-point numbers? I guess more rounding errors would appear in the double type. Could someone give me an example (the best in C ++) because I have no idea how to start with it...
I would be very grateful if you could provide me with a hint. Thanks!
In a C++ implementation using IEEE-754 arithmetic and the “single” (binary32) format for float, this code prints “count = 3”:
int count = 0;
for (float f = 0; f < .3f; f += .1f)
++count;
std::cout << "count = " << count << ".\n";
but this code prints “count = 4”:
int count = 0;
for (float f = 0; f < .33f; f += .11f)
++count;
std::cout << "count = " << count << ".\n";
In the first example, the source text .1f is converted to 0.100000001490116119384765625, which is the value representable in float that is closed to .1. The source text .3f is converted to 0.300000011920928955078125, the float value closest to .3. Adding this converted value for .1f to f produces 0.100000001490116119384765625, then 0.20000000298023223876953125, and then 0.300000011920928955078125, at which point f < .3f is false, and the loop stops.
In the second example, .11f is converted to 0.10999999940395355224609375, and .33f is converted to 0.3300000131130218505859375. In this case, adding the converted value of .11f to f produces 0.10999999940395355224609375, then 0.2199999988079071044921875, and then 0.329999983310699462890625. Note that, due to rounding, this result of adding .11f three times is 0.329999983310699462890625, which is less than .33f (0.3300000131130218505859375), so f < .33f is true, and the loop continues for another iteration.
This is similar to adding ⅓ in a two-digit decimal format with a loop bound of three-thirds (which is 1). If we had for (f = 0; f < 1; f += ⅓), the ⅓ in the source text would have to be converted to .33 (two-digit decimal). Then f would be stepped through .33, .66, and .99. The loop would not stop until it reached 1.32. The same rounding issues occur in binary floating-point arithmetic.
When the amount added in the loop is a small number relative to the large number, these rounding issues are greater. First, there will be more additions, so there will be more rounding errors, and they may accumulate. Second, since larger numbers require a larger exponent to scale them in the floating-point format, they have less absolute precision than smaller numbers. This means the roundings have to be come larger relative to the small number that is being added. So the rounding errors are larger in magnitude.
Then, even if the loop eventually terminates, the values of f in each iteration may be far from the desired values, due to the accumulated errors. If f is used for calculations inside the loop, the calculations might not be using the desired values and may produce incorrect results.
With increasing values the difference between 2 floating point values increases too. There is a point where i+1 results in the same value.
Consider this code:
#include <iostream>
int main()
{
float i = 0;
while (i != i + 1) i++;
std::cout << i << std::endl;
return 0;
}
while (i != i + 1) should be an endless loop, but for floating point variables, it is not.
The code above prints 1.67772e+07 on https://godbolt.org/z/7xf8n8
So, for (float f = 0; f < 2e7; f++) is an endless loop.
You can try it with double yourself, the value is bigger.
Is it possible to initialize a float variable with a hexadecimal float point value in C++?
Something like this:
double d = 0x011.1; // wrong!
The Technical Specification P0245 Hexadecimal floating literals for C++ has been voted into C++17 at the ISO C++ Standards Committee in Jacksonville, Florida on February 2016.
The language C99 also has this feature, and the C++ feature is compatible.
However, as pointed by the Lưu Vĩnh Phúc's comment, the syntax 0x011.1 is not part of the standard. The binary exponent is mandatory for hexadecimal floating-point literals. One reason is to avoid ambiguity of the trailing F within 0x011.1F. Is it the hex digit F of the fractional part or the floating-suffix meaning float?
Therefore append p followed by a positive or negative decimal number, for example: 0x011.1p0.
See the more readable page floating literal page on cppreference.com.
0x | 0X hex-digit-sequence
0x | 0X hex-digit-sequence .
0x | 0X hex-digit-sequence(optional) . hex-digit-sequence
Hexadecimal digit-sequence representing a whole number without a radix separator. The exponent is never optional for hexadecimal floating-point literals: 0x1ffp10, 0X0p-1, 0x1.p0, 0xf.p-1, 0x0.123p-1, 0xa.bp10l
The exponent syntax for hexadecimal floating-point literal has the form
p | P exponent-sign(optional) digit-sequence
exponent-sign, if present, is either + or -
suffix, if present, is one of f, F, l, or L. The suffix determines the type of the floating-point literal:
(no suffix) defines double
f F defines float
l L defines long double
See also the current working draft C++17, chapter § 2.13.4 Floating literals on GitHub: https://github.com/cplusplus/draft/raw/master/papers/n4604.pdf
floating-literal:
decimal-floating-literal
hexadecimal-floating-literal
decimal-floating-literal:
fractional-constant exponent-partopt floating-suffixopt
digit-sequence exponent-part floating-suffixopt
hexadecimal-floating-literal:
hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part floating-suffixopt
hexadecimal-prefix hexadecimal-digit-sequence binary-exponent-part floating-suffixopt
fractional-constant:
digit-sequenceopt . digit-sequence
digit-sequence .
hexadecimal-fractional-constant:
hexadecimal-digit-sequenceopt . hexadecimal-digit-sequence
hexadecimal-digit-sequence .
exponent-part:
e signopt digit-sequence
E signopt digit-sequence
binary-exponent-part:
p signopt digit-sequence
P signopt digit-sequence
sign: one of
+ -
digit-sequence:
digit
digit-sequence ’opt digit
floating-suffix: one of
f l F L
1 A floating literal consists of an optional prefix specifying a base, an integer part, a radix point, a fraction part, an e, E, p or P, an optionally signed integer exponent, and an optional type suffix. The integer and fraction parts both consist of a sequence of decimal (base ten) digits if there is no prefix, or hexadecimal (base sixteen) digits if the prefix is 0x or 0X. The literal is a decimal floating literal in the former case and a hexadecimal floating literal in the latter case. Optional separating single quotes in a digit-sequence or hexadecimal-
digit-sequence are ignored when determining its value. [ Example: The literals 1.602’176’565e-19 and 1.602176565e-19 have the same value. — end example ] Either the integer part or the fraction part (not both) can be omitted. Either the radix point or the letter e or E and the exponent (not both) can be omitted from a decimal floating literal. The radix point (but not the exponent) can be omitted from a hexadecimal floating literal. The integer part, the optional radix point, and the optional fraction part, form the significand of the floating literal. In a decimal floating literal, the exponent, if present, indicates the power of 10 by which the significand is to be scaled. In a hexadecimal floating literal, the exponent indicates the power of 2 by which the significand is to be scaled. [ Example: The literals 49.625 and 0xC.68p+2 have the same value. — end example ] If the scaled value is in the range of representable values for its type, the result is the scaled value if representable, else the larger or smaller representable value nearest the scaled value, chosen in an implementation-defined manner.
The type of a floating literal is double unless explicitly specified by a suffix. The suffixes f and F specify float, the suffixes l and L specify long double. If the scaled value is not in the range of representable values for its type, the program is ill-formed.
As unwind has advised, you can use strtof(). The following snippet decodes Hexadecimal floating literals (without C++17):
#include <iostream>
#include <cstdlib>
#include <cstdio>
int main(int argc, char *argv[])
{
if (argc != 2)
{
std::cout <<"Usage: "<< argv[0] <<" 0xA.Bp-1 => Decode hexfloat" "\n";
return 1;
}
long double l;
double d;
float f;
std::cout <<"Decode floating point hexadecimal = "<< argv[1];
//std::istringstream(argv[1]) >> std::hexfloat >> d;
l = std::strtold(argv[1],NULL); if(errno == ERANGE) std::cout << "\n" "std::strtold() range error";
d = std::strtod (argv[1],NULL); if(errno == ERANGE) std::cout << "\n" "std::strtod() range error";
f = std::strtof (argv[1],NULL); if(errno == ERANGE) std::cout << "\n" "std::strtod() range error";
std::cout <<"\n" "long double = "<< std::defaultfloat << l <<'\t'<< std::hexfloat << l
<<"\n" "double = "<< std::defaultfloat << d <<'\t'<< std::hexfloat << d
<<"\n" "float = "<< std::defaultfloat << f <<'\t'<< std::hexfloat << f <<'\n';
}
No, C++ doesn't support that for literals, it's not part of the standard.
A non-portable solution is to use a compiler that adds this as an extension (GCC does this).
A portable workaround is to parse them from string literals at runtime using e.g. strtof() or strtod() for double.
As pointed out in a comment, you can also opt to store the constants in a C file. Doing so requires that you have access to a C99 compiler though, since hex float literals is a C99-level feature. Since environments with a new C++ compiler but without a C99 compiler (read: Visual Studio) are quite common, that might not be a workable solution.
Update: C++17 supports hexadecimal floating point literals.
Good day, colleagues!
I need to obtain cyclic series on successive numbers from 0 to 255. Is it legal to use unsigned char overflow like this:
unsigned char test_char = 0;
while (true) {
std::cout << test_char++ << " ";
}
Or will be more safely to use this code:
int test_int = 0;
while (true) {
std::cout << test_int++ % 256 << " ";
}
Of course, in real code there will be reasonable condition instead of while (true).
3.9.1/4 "Unsigned integers, declared unsigned, shall obey the laws of arithmetic modulo 2n where n is the number of bits in the value representation of that particular size of integer"
"This implies that unsigned arithmetic does not overflow because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting unsigned integer type"
So, yes it is legal. And the second form is preferred, since it's more readable.
Even though sizeof(char) will always be 1, it is not necessary that a char will be exactly 8 bits. (I am guessing unsigned char will be similar).
So of the two, if given a choice, I would prefer the latter as the former might not even be correct.
btw, You probably intended unsigned int instead of int for the latter? Modulus with negative numbers could get tricky (after the int overflows, as Jimmy noted). If I recollect correctly, I believe it is compiler dependent.
unsigned char, like all other unsigned integral types, follows modulo 2n arithmetic, so basically both your methods are equivalent. Use the first
There is no such thing as unsigned overflow, per 3.9.1/4 as quoted by Erik. However, as Moron says, it is possible that the modulus of the unsigned char number system is greater than 256.
Note that your expression does not store the result of % 256 back to test_int. The safe way to do this is
test_int = ( test_int + 1 ) % 256;
std::cout << test_int << " ";
the output of the 2 samples is completely different.
the first one will print characters (a b c d e f g h ...)
the second one will print integers (0 1 2 3 4 ... 255 0 ...)
anyway it depends if you have a a control for overflowexception (.NET) otherwise in old C++ it the value is always valid and goes from 0 to 255
I am running long simulations. I record the results into a vector to compute statistics about the data. I realized that, in theory, those samples could be the result of a division by zero; this is only theoretical, I am pretty sure it's not the case. In order to avoid rerunning the simulation after modifying the code, I was wondering what happens in that case. Would I be able to realize whether a division by 0 has occurred or not? Will I get error messages? (Exceptions are not being handled at the moment).
Thanks
For IEEE floats, division of a finite nonzero float by 0 is well-defined and results in +infinity (if the value was >zero) or -infinity (if the value was less than zero). The result of 0.0/0.0 is NaN. If you use integers, the behaviour is undefined.
Note that C standard says (6.5.5):
The result of the / operator is the quotient from the division of
the first operand by the second; the result of the % operator is the
remainder. In both operations, if the value of the second operand is
zero, the behavior is undefined.
So something/0 is undefined (by the standard) both for integral types and Floating points. Nevertheless most implementations have fore mentioned behavior (+-INF or NAN).
If you're talking integers then your program should crash upon division by zero.
If you're talking floats then division by zero is allowed and the result to that is INF or -INF. Now it's all up to your code if the program will crash, handle that nicely or continue with undefined/unexpected results.
If you use IEEE floats, then it will return 0 or NaN. If the op1 is 0, you will get undefined. If op1 is higher than 0, you will get Infinity. If op1 is lower than 0, then you will get -Infinity. If you use dividing by 0 directly or in integer , you will get error "Floating point exception".
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
double a = 123, b = 0;
double result = a/b;
string isInfinite = isinf(result) ? "is" : "is not";
cout << "result=" << result << " " << isInfinite << " infinity" << endl;
}
result=inf is infinity
What is the precise meaning of numeric_limits::digits10?
Some other related questions in stackoverflow made me think it is the maximum precision of a double, but
The following prototype starts working (sucess is true) when precision is greater that 17 ( == 2+numeric_limits::digits10)
With STLPort, readDouble==infinity at the end; with microsoft's STL, readDouble == 0.0.
Has this prototype any kind of meaning :) ?
Here is the prototype:
#include <float.h>
#include <limits>
#include <math.h>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
int main(int argc, const char* argv[]) {
std::ostringstream os;
//int digit10=std::numeric_limits<double>::digits10; // ==15
//int digit=std::numeric_limits<double>::digits; // ==53
os << std::setprecision(17);
os << DBL_MAX;
std::cout << os.str();
std::stringbuf sb(os.str());
std::istream is(&sb);
double readDouble=0.0;
is >> readDouble;
bool success = fabs(DBL_MAX-readDouble)<0.1;
}
numeric_limits::digits10 is the number of decimal digits that can be held without loss.
For example numeric_limits<unsigned char>::digits10 is 2. This means that an unsigned char can hold 0..99 without loss. If it were 3 it could hold 0..999, but as we all know it can only hold 0..255.
This manual page has an example for floating point numbers, which (when shortened) shows that
cout << numeric_limits<float>::digits10 <<endl;
float f = (float)99999999; // 8 digits
cout.precision ( 10 );
cout << "The float is; " << f << endl;
prints
6
The float is; 100000000
numeric_limits::digits10 specifies the number of decimal digits to the left of the decimal point you can represent without a loss of precision. Each type will have a different number of representable decimal values.
See this very readable paper:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2005.pdf
Although DBL_MAX ( = std::numeric_limits::digits10 = 15 digits) is the minimum guaranteed number of digits for a double, the DBL_MAXDIG10 value (= 17 digits) proposed in the paper has the useful properties:
Of being the minimum number of digits needed to survive a round-trip to string form and back and get the same double in the end.
Of being the minimum number of digits needed to convert the double
to string form and show different strings every time you get (A != B) in code.
With 16 or fewer digits, you can get doubles that are not equal in code,
but when they are converted to string form they are the same
(which will give the case where they are different when compared in the code,
but a log file will show them as identical - very confusing and hard to debug!)
When you compare values (e.g. by reviewing them manually by diff'ing two log files) we should remember that digits 1-15 are ALWAYS valid, but differences in the 16th and 17th digits MAY be junk.
The '53' is the bit width of the significand that your type (double) holds. The '15' is the number of decimal digits that can be represented safely with that kind of precision.
digits10 is for conversion: string → double → string
max_digits10 is for conversion: double → string → double
In your program, you are using the conversion (double → string → double). You should use max_digits10 instead of digits10.
For more details about digits10 and max_digits10, you can read:
difference explained by stackoverflow
digits10
max_digits10