Search

4.8 — Floating point numbers

Integers are great for counting whole numbers, but sometimes we need to store very large numbers, or numbers with a fractional component. A floating point type variable is a variable that can hold a real number, such as 4320.0, -3.33, or 0.01226. The floating part of the name floating point refers to the fact that the decimal point can “float”; that is, it can support a variable number of digits before and after the decimal point.

There are three different floating point data types: float, double, and long double. As with integers, C++ does not define the actual size of these types (but it does guarantee minimum sizes). On modern architectures, floating point representation almost always follows IEEE 754 binary format. In this format, a float is 4 bytes, a double is 8, and a long double can be equivalent to a double (8 bytes), 80-bits (often padded to 12 bytes), or 16 bytes.

Floating point data types are always signed (can hold positive and negative values).

Category Type Minimum Size Typical Size
floating point float 4 bytes 4 bytes
double 8 bytes 8 bytes
long double 8 bytes 8, 12, or 16 bytes

Here are some definitions of floating point numbers:

When using floating point literals, always include at least one decimal place (even if the decimal is 0). This helps the compiler understand that the number is a floating point number and not an integer.

Note that by default, floating point literals default to type double. An f suffix is used to denote a literal of type float.

Best practice

Always make sure the type of your literals match the type of the variables they’re being assigned to or used to initialize. Otherwise an unnecessary conversion will result, possibly with a loss of precision.

Warning

Make sure you don’t use integer literals where floating point literals should be used. This includes when initializing or assigning values to floating point objects, doing floating point arithmetic, and calling functions that expect floating point values.

Printing floating point numbers

Now consider this simple program:

The results of this seemingly simple program may surprise you:

5
6.7
9.87654e+06

In the first case, the std::cout printed 5, even though we typed in 5.0. By default, std::cout will not print the fractional part of a number if the fractional part is 0.

In the second case, the number prints as we expect.

In the third case, it printed the number in scientific notation (if you need a refresher on scientific notation, see lesson 4.7 -- Introduction to scientific notation).

Floating point range

Assuming IEEE 754 representation:

Size Range Precision
4 bytes ±1.18 x 10-38 to ±3.4 x 1038 6-9 significant digits, typically 7
8 bytes ±2.23 x 10-308 to ±1.80 x 10308 15-18 significant digits, typically 16
80-bits (typically uses 12 or 16 bytes) ±3.36 x 10-4932 to ±1.18 x 104932 18-21 significant digits
16 bytes ±3.36 x 10-4932 to ±1.18 x 104932 33-36 significant digits

The 80-bit floating point type is a bit of a historical anomaly. On modern processors, it is typically implemented using 12 or 16 bytes (which is a more natural size for processors to handle).

It may seem a little odd that the 80-bit floating point type has the same range as the 16-byte floating point type. This is because they have the same number of bits dedicated to the exponent -- however, the 16-byte number can store more significant digits.

Floating point precision

Consider the fraction 1/3. The decimal representation of this number is 0.33333333333333… with 3’s going out to infinity. If you were writing this number on a piece of paper, your arm would get tired at some point, and you’d eventually stop writing. And the number you were left with would be close to 0.3333333333…. (with 3’s going out to infinity) but not exactly.

On a computer, an infinite length number would require infinite memory to store, and typically we only have 4 or 8 bytes. This limited memory means floating point numbers can only store a certain number of significant digits -- and that any additional significant digits are lost. The number that is actually stored will be close to the desired number, but not exact.

The precision of a floating point number defines how many significant digits it can represent without information loss.

When outputting floating point numbers, std::cout has a default precision of 6 -- that is, it assumes all floating point variables are only significant to 6 digits (the minimum precision of a float), and hence it will truncate anything after that.

The following program shows std::cout truncating to 6 digits:

This program outputs:

9.87654
987.654
987654
9.87654e+006
9.87654e-005

Note that each of these only have 6 significant digits.

Also note that std::cout will switch to outputting numbers in scientific notation in some cases. Depending on the compiler, the exponent will typically be padded to a minimum number of digits. Fear not, 9.87654e+006 is the same as 9.87654e6, just with some padding 0’s. The minimum number of exponent digits displayed is compiler-specific (Visual Studio uses 3, some others use 2 as per the C99 standard).

The number of digits of precision a floating point variable has depends on both the size (floats have less precision than doubles) and the particular value being stored (some values have more precision than others). Float values have between 6 and 9 digits of precision, with most float values having at least 7 significant digits. Double values have between 15 and 18 digits of precision, with most double values having at least 16 significant digits. Long double has a minimum precision of 15, 18, or 33 significant digits depending on how many bytes it occupies.

We can override the default precision that std::cout shows by using the std::setprecision() function that is defined in the iomanip header.

Outputs:

3.333333253860474
3.333333333333334

Because we set the precision to 16 digits, each of the above numbers is printed with 16 digits. But, as you can see, the numbers certainly aren’t precise to 16 digits! And because floats are less precise than doubles, the float exhibits has more error.

Precision issues don’t just impact fractional numbers, they impact any number with too many significant digits. Let’s consider a big number:

Output:

123456792

123456792 is greater than 123456789. The value 123456789.0 has 10 significant digits, but float values typically have 7 digits of precision (and the result of 123456792 is precise only to 7 significant digits). We lost some precision! When precision is lost because a number can’t be stored precisely, this is called a rounding error.

Consequently, one has to be careful when using floating point numbers that require more precision than the variables can hold.

Best practice

Favor double over float unless space is at a premium, as the lack of precision in a float will often lead to inaccuracies.

Rounding errors make floating point comparisons tricky

Floating point numbers are tricky to work with due to non-obvious differences between binary (how data is stored) and decimal (how we think) numbers. Consider the fraction 1/10. In decimal, this is easily represented as 0.1, and we are used to thinking of 0.1 as an easily representable number with 1 significant digit. However, in binary, 0.1 is represented by the infinite sequence: 0.00011001100110011… Because of this, when we assign 0.1 to a floating point number, we’ll run into precision problems.

You can see the effects of this in the following program:

This outputs:

0.1
0.10000000000000001

On the top line, std::cout prints 0.1, as we expect.

On the bottom line, where we have std::cout show us 17 digits of precision, we see that d is actually not quite 0.1! This is because the double had to truncate the approximation due to its limited memory. The result is a number that is precise to 16 significant digits (which type double guarantees), but the number is not exactly 0.1. Rounding errors may make a number either slightly smaller or slightly larger, depending on where the truncation happens.

Rounding errors can have unexpected consequences:

1
0.99999999999999989

Although we might expect that d1 and d2 should be equal, we see that they are not. If we were to compare d1 and d2 in a program, the program would probably not perform as expected. Because floating point numbers tend to be inexact, comparing floating point numbers is generally problematic -- we discuss the subject more (and solutions) in lesson 5.6 -- Relational operators and floating point comparisons.

One last note on rounding errors: mathematical operations (such as addition and multiplication) tend to make rounding errors grow. So even though 0.1 has a rounding error in the 17th significant digit, when we add 0.1 ten times, the rounding error has crept into the 16th significant digit. Continued operations would cause this error to become increasingly significant.

Key insight

Rounding errors occur when a number can’t be stored precisely. This can happen even with simple numbers, like 0.1. Therefore, rounding errors can, and do, happen all the time. Rounding errors aren’t the exception -- they’re the rule. Never assume your floating point numbers are exact.

A corollary of this rule is: never use floating point numbers for financial or currency data.

NaN and Inf

There are two special categories of floating point numbers. The first is Inf, which represents infinity. Inf can be positive or negative. The second is NaN, which stands for “Not a Number”. There are several different kinds of NaN (which we won’t discuss here).

Here’s a program showing all three:

And the results using Visual Studio 2008 on Windows:

1.#INF
-1.#INF
1.#IND

INF stands for infinity, and IND stands for indeterminate. Note that the results of printing Inf and NaN are platform specific, so your results may vary.

Conclusion

To summarize, the two things you should remember about floating point numbers:

1) Floating point numbers are useful for storing very large or very small numbers, including those with fractional components.

2) Floating point numbers often have small rounding errors, even when the number has fewer significant digits than the precision. Many times these go unnoticed because they are so small, and because the numbers are truncated for output. However, comparisons of floating point numbers may not give the expected results. Performing mathematical operations on these values will cause the rounding errors to grow larger.


4.9 -- Boolean values
Index
4.7 -- Introduction to scientific notation

341 comments to 4.8 — Floating point numbers

  • Pablo Asenjo Navas-Parejo

    Hey! Why doesn't this function work? (howManyDecimalsIn()). It works with some numbers (like 0.3 or 4.44) but not with some numbers (like 9.999999 or 4.44444) I'm sorry for spanish comments.

    I'm in love with your guide, thank you!

    • Pablo Asenjo Navas-Parejo

      I have noticed that in the case of 6.666, there is a moment when isInteger(6.666 * 10^3) evaluates to false, while isInteger(6666) evaluates to true...

    • Floating point inaccuracy.
      Add

  • SM.Haider

    When will floating point variables ever be desired, and will floating point arithmetic always output rounding errors or precision issues?

    • > When will floating point variables ever be desired
      Whenever you want to calculate something that's not a whole number.

      > will floating point arithmetic always output rounding errors or precision issues?
      Yes. Most of the time this error is negligible. If you need spot-on results, you have to write your own type (covered later).

  • alfonso

    In section "Floating point range", in the table appears  80-bits (12 bytes). Is this an error or I miss something?

    • Alex

      You're not missing anything, it just could be made a bit clearer.

      I added the following to the lesson: "The 80-bit floating point type is a bit of a historical anomaly. On modern processors, it is typically implemented using 12 or 16 bytes (which is a more natural size for processors to handle)."

      See https://en.wikipedia.org/wiki/Extended_precision#x86_extended_precision_format for some history on the format.

  • Joe

    Isn't it a bit needless to have to put the suffix 'f' to indicate that I want the value to be a float type when I've already stated the type I want it to be at the beginning of the statement.

    I get that the default is to interpret any float pointing literals as double but why would that override my defining of what type a particular variable is.

    • Hi, see my comment here https://www.learncpp.com/cpp-tutorial/floating-point-numbers/comment-page-4/#comment-387100

    • Alex

      The type of the variable can be deduced from the initializer (using the auto keyword, covered later)
      The type of the initializer can not be deduced from the variable.

      So it's kind of possible to do what you're suggesting, just in the other direction.

  • Iliad

    Typo on last word of that line. (rpecision -> precision).

  • Ram

    As pointed out in tutorial in double we have 17 digits of precession, then from where do we get that extra digits in double variable @a, are they all random or are they are really stored inside @a.

    Here output is

    • Alex

      They aren't stored. They're generated as part of the conversion that converts the binary representation back into a decimal value.

    • ram

      First of all, thank you very much for your reply. But I can't understand how conversion could be so large or small, could you please elaborate in detail using the example of var @a or in general.

      • The internal representation of floating point numbers isn't standardized in C++. Judging by the number you're getting, your compiler is using the IEEE 754 format.
        Floating point numbers are stored as sign, mantissa and exponent. Each part has a fixed precision (1bit sign, 11bit exponent, 52bit mantissa).
        The floating point number has to be represented by
        (-1)^sign * mantissa * 2^(exponent - 1023)
        Where '^' denotes "to the power of".
        .000000000000000003 cannot be represented by the above formula with the given precision, so the next closest number is used, which is the number you saw.

        See these links for a more detailed explanation
        https://www.wikihow.com/Convert-a-Number-from-Decimal-to-IEEE-754-Floating-Point-Representation
        https://en.wikipedia.org/wiki/Double-precision_floating-point_format

  • Louis Cloete

    In the third case, it printed the number in scientific notation (if you need a refresher on scientific notation, see lesson %Failed lesson reference, id XX%). (just below the "Floating point range" heading)

    Seems like your link isn't working.

  • Hassan

    Thanks a lot for developing this amazing tutorial!

    I just have a simple question regarding the newline with use of

    why are you using

    here whereas you advised in an earlier lesson to prefer

    over it to avoid what you mentioned "redundant flush"?

    • Alex

      Many of these lessons were written a while back, and aren't fully compliant with the most modern best practices yet.

      I'm working on getting them all updated, but it's slow going because there's a ton of content.

      Whenever you see an inconsistency between a stated best practice and what an example is showing, follow the best practice.

  • Old M8

    Why did you use direct initialization in the examples and not uniform?

    • Alex

      This lesson hasn't been updated to be fully compliant with C++11 best practices. I'm working on it.

      • Old M8

        Ah, yeap, no problem.

        I don't really get what you mean on the about/contact page when you said "before making a career shift to software product owner". Isn't everyone with a computer a software product owner?

        Have you thought about making a way for select users to be able to edit the material and making it not visible to the public until approved by someone higher up?

        And lastly thanks for providing the website and its' content for free.

        • Alex

          "Software product owner" basically means I no longer code, but rather I look for business opportunities, developer requirements for features, prioritize feature requests, etc...

          I have not only thought about allowing users to edit content, I've experimented with it in the past. The challenge is that WordPress doesn't have a good way to do this for in-article edits (only for entire articles). Maybe there's a plugin to add that capability that I could explore further.

          And you're welcome. Thanks for visiting!

  • Dear Teacher, please let me following question:
    I want to create a program asking user enter a double number in format a/b e.g. 3/2 and program output 1.5.
    With regards and friendship
    Georges Theodosiou

  • Gejsi

    First of all thanks a lot for this site and very instructive and easy to understand tutorials! It's like I'm schooling myself and learning really fast in such amount of time.
    I tried to create a program that takes in as input your current Year/day/time and Year/day/time of birth to output the age with as much knowledge as I mustered so far. I'd like to ask if possible if I could improve my code or if I can do better in some areas.
    Note that the format for days is 365 so when it asks for days you have to do some math. For instance if it's February 18 then you have to count all days in this year up to feb 18. Same with hours which is 24 hour format.
    Thank you for the tutorials once again!

    #include <iostream>
    using namespace std;

    double age(int year, int day, int hour)
    {
        double h{1};
        double d{h * 24};
        double y{365.25};
        cout << "Enter current year: ";
        double cyear{};
        cin >> cyear;
        cout << "Enter current day: ";
        double cday{};
        cin >> cday;
        cout << "Enter current hour: ";
        double chour{};
        cin >> chour;
        double thours{cyear * y * d * h + cday + chour};
        double pthours{year * y * d * h + day + hour};
        double hage{pthours - thours};
        return hage;
    }

    double yearDayHours(double totalHours)
    {
        return totalHours / 24 / 365;
    }

        int main()
        {
            int y{};
            int d{};
            int h{};
            cout << "Enter year of birth: ";
            cin >> y;
            cout << "Enter day of birth: ";
            cin >> d;
            cout << "Enter hour of birth: ";
            cin >> h;
            cout << yearDayHours(age(y, d, h));

            return 0;
        }

    • Hi!

      Please use code tags when posting code.

      * Don't use "using namespace".
      * Use double literals when calculating with doubles (1.0 instead of 1, 24.0 instead of 24 etc.)
      * Initialize variables to a specific (0) value.
      * You're using the same name style for functions and variables, this can lead to confusion.
      * Prints a line feed when you program has finished.
      * Don't use abbreviations unless their meaning is obvious.

  • I've always hated these datatypes, most of all since they appear to be... how to say that in proper English (my first language is Dutch)... unreliable....
    Now I began coding in the 1980s in BASIC (like many of us back then), and there it was often recommended to use integers as they are faster than non-integers (and of all issues the old BASIC had, speed was its biggest issue), and when I moved to other languages I often see the numbers coming after the decimal point change, seemingly randomly, sometimes even leading to 1.x becoming 2.x, but it did cause me to avoid them, and even when I only need 3 decimals to use 1000-folds of the numbers in the calculation and the 'cheat' on the output making users believe they see a non-interger. I don't think that's the most elegant solution, but at least I was sure the results shown on screen were always correct.

    To demonstrate, this code in BlitzMax:

    Outputs: 1.00199997 which is NOT the number I asked for.... Now the difference is small, but in complex calculations this did lead to wrong outcomes with pretty terrible results in the functioning of the program as a whole, and BlitzMax is not the only language in which I encountered this issue.

    Now are C and C++ in this issue? Are these more precise, or is that compiler dependent? Especially since I plan to work open source (which I mostly already do in the languages I used so far) different settings with compilers can haunt me on this one, so that's why I wanna be sure before I start a "serious" project in C++ :)

    I did try this (basically an exact translation of the code in BlitzMax to C++) and that gave the correct outcome, but I want to make sure all compilers are the same on this to prevent any issues ;)

    • Hi!

      * Line 3: Initialize your variables with brace initializers.
      * Line 4: Missing 'f' postfix

      Quoting the standard § 6.7.1 63N4791
      "The type double provides at least
      as much precision as float, and the type long double provides at least as much precision as double. The set of values of the type float is a subset of the set of values of the type double; the set of values of the
      type double is a subset of the set of values of the type long double. The value representation of floating-point types is implementation-defined."

      So, no guarantees about the precision about individual types.
      You can use @std::numeric_limits::is_iec559 to check if the compiler uses a standardized floating point representation, and, if it doesn't, fall back to a custom type.

  • Asgar

    I have to say that these chapters about numbers are really helpful. I am learning so much! I am intentionally spending much time to go over each line written. The writer has done a very meticulous job quite sincerely.

    Speaking about INF, how come the program is not crashing even though a number is being divided by a zero in order to attain infinity?

    • > how come the program is not crashing even though a number is being divided by a zero
      The behavior of division by 0 is undefined. Most compilers use a floating point representation that support infinity, so they use that. But you shouldn't assume anything about undefined behavior.

      @Alex
      This should be noted in your example. Or just use @std::numeric_limits<double>::infinity() along with @std::numeric_limits<double>::has_infinity to get the infinity values instead of division by 0.
      C++20 will standardize signed integer representations. Let's hope we'll get standardized floating points eventually.

  • Alireza

    HELLO (^+^)

    Does it overflow ?

      • Alireza

        Thank you for replying,

        But what are the following errors for ?

        • For mixing types.
          Line 7 converts a float to double.
          Line 8 converts a long double to double and a double to a float.
          Increasing floating point precision isn't a problem, but you should use casts when you do so (Casts are covered later).
          You'll get problems when you decrease precision (eg. double to float).

          • Senna

            Thanks again,
            Do you mean 'static_cast()' ?
            Is one of the problems when I decrease the precision overflow or it has a another problems ?

            • The problem is the loss of precision.

              @db can store the given number, but @fl can't. It will be converted to the closest number that a float can store, which can be way off.
              On my system, the above code outputs

              We're off by 100 billion.
              The same happens with the fractional part.

  • [code]Alan[/code]

    Hello there,
    Between double and float data type, Is the limitation in decimal fraction number or on the piece of integer ?

    • double has a guaranteed higher precision than float. So the fractional part is more precise.
      Other than that there are no requirements to the types.
      @std::numeric_limits gives you all kind of information about numeric types.

      http://www.cplusplus.com/reference/limits/numeric_limits/

  • HaverError-mixed up

    Hello!
    Thanks for this tutorial.

    I have a problem, I'm using Qt Creator 4.7 and When I write following program I get an error and I don't know why it occurs.

    And I get this following error, but the above program is compiled and run as well but the following error is a warning:

    When I initialize the variable dv as an integer, there's no problem:

    Thank you

    • * Line 13, 14: Initialize your variables with uniform initialization. You used copy initialization.

      1.88888888888888 is a double. @dv is a long double.
      Use 1.88888888888888l. The 'l' in the end means that it's a long double.

  • Jeremy

    Quick question on the rounding of floating point numbers.

    As we know that rounding errors occur as well as a cut off point on the number of decimal places depending on the data type used

    How does the computer know that (1 / 3) * 3 = 1?

    Since 1/3 is 0.3333333... and there is a cut off point on those decimal places, how does it calculate it precisely back to 1 if we multiply that result by 3 instead of ending up with something like 0.999999999?

    • Hi Jeremy!

      The result is so close to 1, that because of the error caused by the multiplication, the result is 1.

      Example with 1/3:
      operation = real = computer
      1.0 / 3.0 = 0.3... = 0.333333333333333333342
      0.333333333333333333342 * 3.0 = 1.000000000000000000026 = 1.0

      1.000000000000000000026 is so close to 1.0, that for your computer, it is 1.0

      Once you get to bigger numbers, and bigger errors, you won't be that lucky.

      Example with 1/41:
      operation = real = computer
      1.0 / 41.0 = ... = 0.0243902439024390243894
      0.0243902439024390243894 * 41.0 = 0.9999999999999999999654 = 0.999999999999999999946

      We don't get 1.0 as a result.

      The internal representation of floating point values is implementation defined, you might experience different results.

  • Abdul Majeed

    how to print exactly 12.56464564896465465465498465465461 value same as

    • C++ doesn't have a built-in type that supports numbers that precise. You'd have to write your own type (Covered later).
      If you just want to print that value and don't do any processing with it, you can print it as a string.

  • Hi
    Please to explain why we do literals for f value? You said that the compiler should treat f as float value! but we already declared it as float. so why we need to confirm to the complier to treat it as float ? I read about literals but did not fully get it. Thanks
    float f;
        f = 9.87654321f; // f suffix means this number should be treated as a float

    • - The type of @f can be deduced off of the value, this is covered later.
      - You might want to do parts of a calculation in higher/lower precision than another part.
      - The type of the value is determined before the assignment happens. ie. The type of the variable is ignored until after the calculation has finished.

  • Ajalle Perfej

    I'm having a problem with floating-point numbers in this code:

    The specific problem is with idiot-proofing the entry of fractional amounts of -1 < x < 1. Larger fractions are truncated just fine but fractions more than -1 and less than 1 cause an infinite loop. Please advise.

    • Your program doesn't support floating point numbers. You're using long, which is an integer type.
      Your program encounters an infinite loop, for numbers like 0.1, because
      line extracts the 0
      -> line 47 fails
      -> ".1" is left in the input stream
      -> '.' cannot be extracted into an int
      -> the stream enters a failed state (covered later) in which it is now stuck

      You need to use double or float

      • Ajalle Perfej

        Thank you for your reply and your assistance.

        I'm specifically using longs instead of floating point numbers because there is an infinite number of floating-point divisors for every floating point number.

        I managed to solve the problem after reading lesson 4.4 on strings, as follows:

        Here is the entire program revised after reading lesson 4.4 (I tested it and it works fine):

        • That partially fixes the problem. The proper solution is covered in lesson 5.10.

          Suggestions
          * Unnecessary forward declarations. Move @main above other functions.
          * Same name style for functions and variables. This can lead to confusion.
          * Avoid global variables
          * Line 49, 64: Initialize your variables with uniform initialization
          * Line 66: Don't pass 32767 to @std::cin.ignore. Pass @std::numeric_limits<std::streamsize>::max().
          * Line 67 doesn't do anything
          * Line 81-86: Should be a for-loop

          • Ajalle Perfej

            Here's the cleaned-up source code. I didn't initialize the variable on line 61 (old line 49) because of the console input.

            • > I didn't initialize the variable on line 61 (old line 49) because of the console input.
              You mean 31? Although @std::cin overrides variables on failed extraction, you shouldn't assume any function can handle uninitialized variables. Initializing all variables helps preventing you from writing unpredictable code, which is terrible to debug. Line 98, 99 should be merged.

              The backslash in line 36 is more confusing than helpful. Non-string lines can be split without using a backslash.
              Line 62-66 should be a for-loop (I'm assuming you have previous programming knowledge or read ahead).
              You can use raw strings to preserve formatting

              that way you don't have to add \n\ everywhere

              • Ajalle Perfej

                I cleaned up the code again, but am not sure what value I should initialize

                to. I tried

                and that didn't work. Instead I've initialized the variables to 0, as that's a value that gets thrown out by the console input getter.

  • Anonymous

    So far this has been the only topic I've found it difficult to understand. Do we use float if we want less precision (like small decimal numbers, 3.4) and to use up less memory? And double to give us more precision such as 99.67462775848, but it'll use up more of the memory?

    I tried to scientific notations quiz:

    scientificnotation.cpp

    I'm still not sure when to use the f suffix. Whenever I used it for "double h(666.262002f)", it printed out the same value without the f suffix. Also for

    double f(0.0000000008);
    std::cout << std::setprecision(11);
    f = 8e-10;
    std::cout << "f: " << f << std::endl;

    , it prints out 8e-10 and not the value in the brackets. What did I do wrong?

    Also I'm not sure how to keep the trailing zeros!

    Lastly I keep getting this warning : scientificnotation.cpp(24): warning C4244: '=': conversion from 'double' to 'int', possible loss of data

    Any help would be appreciated and sorry for any inconvenience. I just want to perfect my knowledge on every topic before I move on.

    • You're initializing your variables but overriding their values before using them. That's pointless. Initialize them with their desired value.
      Initialize your variables with uniform initialization.

      > I'm still not sure when to use the f suffix
      Whenever you write a number that's supposed to be a float. Not for doubles, not for ints, only for floats.

      > it prints out 8e-10 and not the value in the brackets
      You initialized @f to 0.0000000008 but changed its value to 8e-10 before printing it.

      > I'm not sure how to keep the trailing zeros
      Use @std::fixed to print exactly the precision set via @std::setprecision

      > I keep getting this warning
      float and double are different types. Don't mix them.

      • Anonymous

        Hi. I've made improvement to the code and got the exact values in the quiz. Thanks for all your help! Could you check for any further improvement? Thanks for taking your time to help beginners! Idk how you have the time to do it :)

  • George

    Regarding question number 6 for those who got it wrong because they thought that the answer should have had six significant digits.
    Trailing zeros in a whole number with no decimal shown are not significant, which is why the answer has three significant digits.

    Had the number included a decimal at the end, the number would have had six significant digits:
    EX: 146000.
    1.46000E5

  • Dharmesh Singh

    I was not able to understand how you Inf is equal to 5.0, Also, if you only used cout for the double value, how come you got #Inf with it.

    • Alex

      In mathematics, any positive number divided by 0 is infinity. inf is not equal to 5.0, 5.0 / 0.0 = inf. The inf that gets printed is how the floating point representation is telling you that you did something to generate an infinite value.

  • Shri

    When I have this program:
    case 1)
    float f = 12.345678901f;
    std::cout << f << std::endl;

    output is :
    12.3457

    case 2)
    std::cout << std::setprecision(8) << std::endl;
    float f = 12.345678901f;
    std::cout << std::fixed << f << std::endl;

    the output is:
    12.34567928

    case 3)
    when I change the program to:
    std::cout << std::setprecision(8) << std::endl;
    float f = 123.45678901f;
    std::cout << std::fixed << f << std::endl;

    the output is:
    123.45678711

    As per case 1) output, it seems like float has 6 digits of precision on my compiler.
    as per case 2) output, it seems like float has 8 digits of precision on my compiler.

    I have 2 questions:
    question 1 :
    I don't understand what's happening in case 3), how many digits of precision is being seen in case 3?

    question 2:
    I don't understand why I'm getting 2 different digits of precision for float in case 1) and case 2)

    Please help.

    • Alex

      The definition of precision is how many significant digits the variable can hold without error. Floats have between 6 to 9 decimals of precision, and std::cout defaults to 6 digits of precision (being conservative).

      The answer to both questions is the same: when you use std::fixed, this causes the number to print with as many numbers to the right of the decimal as you've assigned via std::precision. This may exceed the actual precision of the underlying number itself.

      • Shri

        Got it! Thanks for replying!

        I now understand that in case 2), although the output is 123.45678711, it does not mean that the precision for float changed from 6 (as seen in case 1) to 8, its rather that by chance the output was 123.45678711 when it could easily have been 123.45600000.

        Please correct me if I'm wrong!

  • pacifque

    can someone help me how to do this with C, please Pick 3 food items (main meal, side, drink, for example)
    Display them for the user, like this example:

  • Bjorn

    Dear Alex,

    What do you recommend C or C++ and why ? I recently checked TIOBE index and it says JAVA and C are the most popular language to learn. But I want to understand malware and maybe later do something with AI or gamehacking.

    Thanks

    • Hi Bjorn!

      Java is pretty much only used in programming courses and on Android.
      C is used on some embedded systems and regular programs/libraries.
      C++ is C (almost), but with more features, allowing you to spend you time more efficiently.

      > malware
      C++ (Or JS if you're targeting the web)

      > AI
      Python is pretty popular there I think.

      > gamehacking
      You're best of using the language the game was written in. In most cases, it's C or C++, but you can use C++ for a C game.

    • Alex

      My 2c: I recommend C++. I find object oriented programming results in better organization and maintainability of large-scale programs. It's much easier to learn C (if needed) than vice-versa. These days, I'd argue C is only better for niche use cases: embedded code, when you need to interact with other languages that only have C bindings, etc...

  • Dear Teacher, please let me say you regarding number 0.0000000008's scientific notation, Scientific Notation Converter at
    https://www.calculatorsoup.com/calculators/math/scientific-notation-converter.php
    for 8e-10 (c++ output) returns 0.000000000. For 8.0e-10 returns 0.00000000080, and for 8.0e-9 returns 0.0000000080 (1 zero less, left to 8). Only for 8.e-10 returns 0.0000000008, the correct value. My conclusion is that scientific notation is not universal, there are slight differences in the various software. Regards.

  • Dear Teacher, please let me send you following strange program with strange result output by
    https://www.onlinegdb.com/online_c++_compiler

    Result:
    -2147483648
    -2147483648
    0
    Regards.

    • nascardriver

      Hi Georges!

      You're dividing by zero. Since your dividend is a double your result will be a double too. x / 0.0 returns std::numeric_limits<double>::infinity(). When converting this to an int you'll get -2147483648 (all ones in binary).
      I assume 0 / 0 works, because your computer stops executing when it notices that the divided is zero. Division by 0 with it's will cause your program to crash.

      • Dear nascardriver, please let me two comments:
        1. Program

        outputs
        5
        It means machine accepts only the integer part of number for, type is int.
        2. Strange is that in my first message first value of b is positive and second negative, but in output both results are negative.

        • Alex

          5.0 / a is a floating point division. int b = 5.0 / a is a floating point division that is implicitly cast to an integer upon assignment to int b.
          a / a is an integer division because a is an int.

          • Dear Teacher, please accept my many thanks for you replied, and for your helpful answer. Fact is that c++ does not agree with math, in latter division by zero is undefined. In former, situation is complicated depending on whether numbers are integer or rational.

          • Graham

            So basically he is trying to use a decimal in an integer (to my understanding illegal in terms of cpp)

  • Zane

    When I need to know why on something, I can't move forward until I do. This is driving me nuts.

    int x(5); // 5 means integer
    double y(5.0); // 5.0 is a floating point literal (no suffix means double type by default)
    float z(5.0f); // 5.0 is a floating point literal, f suffix means float type

    In the second definition, we use the word double to declare y. Why does having no suffix mean it is a double by default even matter? We used double. It declares it that way.
    Following that question, in the third definition, we use float to define. WHY do we need to use the f suffix if we're already declaring it as a float type of a floating literal? Which begs the question, why is there even a default type or suffix needed in either case, if we are using the appropriate descriptor in the initial definition in the first place? It seems to me like we're specifying what type it is twice. What am I missing?

    • Zane

      A follow up thought, to better explain my confusion, would be thus:

      If no f suffix means double type as default, would then float y(5.0); // mean that it is a double type by default since the f suffix wasn't used?
      Or that double z(5.0f); // is a float type, even though we declared with double?

      (I think) Obviously not, but see how I am getting confused? I read further in the lesson, and googled. I don't think I know enough to know what I need to google, to figure out what the hell I'm confused on. Ha.

      • nascardriver

        No. If you declare a variable as float that variable will always be a float. You can initialize/assign it other types, but you shouldn't.

      • Alex

        There is currently no way to tell the compiler "make this literal the same type as the variable it is initializing".

        However, the inverse is possible: you can tell C++ to make the type of a variable the same type as the initializer using the auto keyword:

        This is one way to address the redundancy you're noticing.

    • nascardriver

      Hi Zane!

      A little example:
      You'll learn about function overloading where you have two functions with the same name but different parameters.

      I'm sure there are more reasons for having different numbers, just use the suffix that corresponds to your data type.

      • Zane

        Annotation, reference, and identification. Good enough reasons as any. Thank you for the explanation and answer to both of my comments. I appreciate the time you take out of your day to answer my questions.

        Though I am curious as to how we'll manage to get our compilers to not bitch about functions with the same name. Unless it is that it is really just the same function with different parameters.
        Are function(int a) and function (int b) considered different functions entirely? I understood them to be the same function with different parameters.
        Thanks again!

        • nascardriver

          The name of the parameters doesn't matter. The compiler cares about

          * function name
          * parameter types
          * parameter order
          * things that are covered in future lessons

          If all these things match for two functions you'll get a compilation error, because you can't have two definitions of the same function. If at least one thing is different, it is considered an entirely different function. The compiler knows which function you want to call based on the arguments passed.

            • vbot

              I must admit, I was confused at this point too.

              Now I understand this:

              Declaring a variable as float does not automatically SET the value assigned to it to the same type (float). A float variable must be assigned a float value ("f" suffix).

              • Alex

                > Declaring a variable as float does not automatically SET the value assigned to it to the same type (float).

                This is not correct. Float variables can ONLY hold float values. If you try to assign or initialize a non-float value to a float variable, the compiler will attempt to convert that value to a float. If the compiler is successful in doing so, the code will compile (possibly with a warning). If the compiler is unsuccessful, you will get a compile error.

                Since you mention "f" suffix, let's take a look at this using some literal values:

                In the f1 case, 5.0f is a float literal, so the float value 5.0 is initialized to float variable f1. Since they are the same type, no conversion is necessary.
                In the f2 case, 5.0 is a double literal. So when double value 5.0 is initialized to float variable f2, the double value 5.0 must be converted to a float value 5.0 before it can be assigned to f2. This may result in a loss of precision or rounding errors.

  • Matha

    Can you give me the coding solution of how to convert the quiz problems into scientific notation?

    • Kio

Leave a Comment

Put all code inside code tags: [code]your code here[/code]