Problem with Nan output

When I run this code, the result is nan.
Sorry, I don't want to upload my bad and lengthy code into thread but I dont know this unexpected output related to whether part in the code so I copy the whole.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include<iostream>
#include<string>
#include<iomanip>
using namespace std;

const double color_per_in =0.10;
const double regular_per_in =0.15;
const double fancy_per_in =0.25;
const double paper_per_in =0.02;
const double glass_per_in =0.07;

int main()
{
	double length, width, crown, peri, area;
	double color_price, crown_price, regular_price, fancy_price, total_price;
	string choice_color;
	char ch, type;
	
	cout<<fixed<<showpoint<<setprecision(2);
	
	cout<<"Enter the length and width (in inches) of the picture: ";
	cin>>length>>width;
	cout<<endl;
	
	cout<<"Enter the type of frame: ";
	cin>>type;
	cout<<endl;
	
	cout<<"Enter your choice of color to color the frame: ";
	cin>>choice_color;
	cout<<endl;
	
	cout<<"Do you want to put the crowns on your frame ?(Y/N)";
	cin>>ch;
	cout<<endl;
	if (ch=='Y')
	{
	cout<<"Enter the number of crowns: ";
	cin>>crown;
	cout<<endl;
	crown_price=crown*0.35;
	}
	
	peri=length + width;
	area=length*width;
	
	if ((choice_color=="white")||(choice_color=="White")) cout<<"The cost of coloring the frame is: $0"<<endl;
	else {
		color_price=peri*color_per_in;
		cout<<"The cost of coloring the frame is: "<<color_price<<endl;
		}
	
	cout<<"The cost of putting a cardboard paper is: "<<area*paper_per_in<<endl;
	cout<<"The cost of putting glass is: "<<area*glass_per_in<<endl;
	
	switch (type)
	{
		case 'r':
		case 'R':
			regular_price=peri*regular_per_in;
			cout<<"The cost of your regular frame is: "<<regular_price<<endl;
			break;
			
		case 'F':
		case 'f':	
			fancy_price=peri*fancy_per_in;
			cout<<"The cost of your fancy frame is: "<<fancy_price<<endl;
			break;
		default:
			cout<<"Invalid type!"<<endl;
			
	}
	total_price=color_price+(area*paper_per_in)+(area*glass_per_in)+crown_price+regular_price+ fancy_price ;
	cout<<"The total cost of framing your picture: "<<total_price<<endl;
	
	return 0;
}		


Sample Run:
The cost of coloring the frame is: 3.00
The cost of putting a cardboard paper is: 4.00
The cost of putting glass is: 14.00
The cost of your regular frame is: 3.50
The total cost of framing your picture: nan

In the last sentence, it said "nan". In this section

 
total_price=color_price+(area*paper_per_in)+(area*glass_per_in)+crown_price+regular_price+ fancy_price 


If I delete regular_price or fancy_price the result is normal, but if I let both of two in there, the result is nan. I have no idea how it works.
Initialise regular_price and fancy_price (line 15).
@JLBorges: Thank you, now it works. But can you give me more detail why to do that and what the origin of this problem is.
Last edited on
Let us take these one by one:

Using the value of an uninitialized and unassigned scalar results in undefined behaviour. For example:
1
2
3
double a = 34.6 ;
double b ; // uninitialised
double c = a + b ; // undefined behaviour 



In the original code, regular_price and fancy_price were not initialized at the point of their definition (line 15).
The switch switch (type) assigned values to either one or the other, but not both. So one of them would remain uninitialised and unassigned, and
total_price=color_price+(area*paper_per_in)+(area*glass_per_in)+crown_price+regular_price+ fancy_price ;
engenders undefined behaviour.


NaN means not a number; it represents an undefined or unrepresentable value. https://en.wikipedia.org/wiki/NaN
A numeric operation with a NaN operand yields NaN. For instance, 5.78 + NaN == NaN


An uninitialised floating point value could be anything at all; it could hold some representation of NaN (there are a very large number of possible bit patterns that can represent NaN).
IEEE 754 NaNs are represented with the exponent field filled with ones (like infinity values), and some non-zero number in the significand (to make them distinct from infinity values); this representation allows the definition of multiple distinct NaN values, depending on which bits are set in the significand, but also on the value of the leading sign bit

So it is not very surprising that using an uninitialised value in a floating point calculation yielded NaN.


To minimise the probability of mistakes of this kind,
postpone the definition of a local variable till we are close to the point of its first use; till we know how to initialize it.
http://stackoverflow.com/questions/6429460/should-one-keenly-consciously-attempt-to-postpone-variable-definitions-as-long
Last edited on
I must add that there is no reason to have both regular_price and fancy_price, as only one of them is used. Replacing them with one variable like frame_price will be better.

Additionally if you want to test values for NaN or simply to play with them, know that almost all comparsions with NaN returns false (aside from != which always returns true).
1
2
3
4
5
6
7
8
9
#include <iostream>
#include <iomanip>
#include <cmath>

int main()
{
    double d = 0.0/0.0;
    std::cout << std::boolalpha << (d == NAN) << '\n' << (d == d)  << '\n' << (d != d);
}
false
false
true

Topic archived. No new replies allowed.