I was trying to make an output/input calculator with C++ - c++

I am self teaching my self teaching myself C++
but I am having a trouble make a simple input/output calculator.
Here is what I have come up with:
#include <iostream>
using namespace std;
int main()
{
cout << "THIS IS TEST CALCULATOR!" << endl;
int fn,sn,dvi; //fn- FIRST NUMBER, sn - SECOND NUMBER
cout << "Please type in the first number: " << endl;
cin >> fn;
cout << "Please type in the second number: " << endl;
cin >> sn;
cout << "Please choose type ( type in one: division, multiplication, subtraction, addition or modulus): "<< endl; //Asks for the type on calculation; needs to type in one.
std::string tp;
cin>>tp;
dvi = (fn/sn); // division
if (tp == "division"){
cout<<fn<<" divide by "<<sn<<" is "<<dvi<< endl;
}
}
result:
8/6 = 1.333333... not 1

You are performing integer division, and therefore 8/6 is 1. If you want floating point arithmetic, you could change fn,sn and dvi to float instead of int, or you could simply cast one or both of the arguments to a float (or double).
See this question for more in-depth answers.

Since the decalred variable type is int you will always get the floor of number.
All three should be of type float or double. Else dvi can be of this type and typecast the fn and sn to same type (float/double) during division.

When dividing integers you get integer values not decimal ones. To solve your problem you either declare them float or double or cast the operation.
double dvi = ((double)fn / (double)sn); // division

Instead of declaring fn,sn,dvi as ints, you should declare them as doubles:
double fn,sn,dvi;
Otherwise, dividing integers by integers in C++ will truncate the numbers to a smaller whole number. For example: 5/3 would equal 1, even though in reality it equals 1.6667. C++ will not round up to 2.0, it will round down to 1.
Another workaround for this issue if you're not using variables is to add the decimal to whole numbers so that the compiler recognizes them as doubles. For example: 5.0/2.0 = 2.5

The problem in your code is that you are dividing 2 variables that are of type int, and storing it in a variable that is also of type int. All three variables:
fn
sn
dvi
are of type int in your code. An int variable only stores a whole integer number, ranging from positive infinity to negative infinity. This means that when you divide 2 numbers that do not produce an integer, the floating point value is rounded off so that it can be stored in the int variable, which in your case is dvi. In addition, even if dvi alone is of data type float, your division will still round to a whole number as you have divided two variables of data type int, namely fn and sn, and in c++, when two integers are divided, the end result is always rounded off regardless of the data type of the variable it will be stored in.
The easiest way to get around the problem is to change the declaration of these variables to:
double fn, sn, dvi;
NOTE: I use double here, as it can store a more precise value since it has 8 bytes allocated to it in contrast to 4 for a float.
This is the easiest way to get around your problem. Alternatively, we can use casting in the mathematical step of your code; in that case we would declare the variables as:
int fn, sn;
double dvi;
Then in the step where you divide the numbers, you can do the following:
dvi = (double)(fn/sn);
This is called casting; the compiler here is "forced" to treat the end result of this division as a double. In your case it will work, as you are dividing numbers, however, as a side note, it cannot be done in all cases (you cannot cast a string as a float for example). Here is a link if you want to learn more about casting:
Typecasting in C and C++
A third way, simpler than casting would be to do the following:
dvi = (fn/sn)*1.0;
This can be done only if dvi is of type float or double. Here, the mathematical operation involves a float, so all values are not of type int. As a result, the precision of the value is preserved with a decimal point, in your case, it will store 1.33333333333... instead of 1.
Sorry for the late reply, I couldn't get time to answer your question yesterday.

Related

Implicit conversion from long long to float yields unexpected result

In an attempt to verify (using VS2012) a book's claim (2nd sentence) that
When we assign an integral value to an object of floating-point type, the fractional part is zero.
Precision may be lost if the integer has more bits than the floating-point object can accommodate.
I wrote the following wee prog:
#include <iostream>
#include <iomanip>
using std::cout;
using std::setprecision;
int main()
{
long long i = 4611686018427387905; // 2^62 + 2^0
float f = i;
std::streamsize prec = cout.precision();
cout << i << " " << setprecision(20) << f << setprecision(prec) << std::endl;
return 0;
}
The output is
4611686018427387905 4611686018427387900
I expected output of the form
4611686018427387905 4611690000000000000
How is a 4-byte float able to retain so much info about an 8-byte integer? Is there a value for i that actually demonstrates the claim?
Floats don't store their data in base 10, they store it in base 2. Thus, 4611690000000000000 isn't actually a very round number. It's binary representation is:
100000000000000000000111001111100001000001110001010000000000000.
As you can see, that would take a lot of data to precisely record. The number that's actually printed, however, has the following binary representation:
11111111111111111111111111111111111111111111111111111111111100
As you can see, that's a much rounder number, and the fact that it's off by 4 from a power of two is likely due to rounding in the convert-to-base-10 algorithm.
As an example of a number that won't fit in a float properly, try the number you expected:
4611690000000000000
You'll notice that that will come out very differently.
The float retains so much information because you're working with a number that is so close to a power of 2.
The float format stores numbers in basically binary scientific notation. In your case, it gets stored as something like
1.0000000...[61 zeroes]...00000001 * 2^62.
The float format can't store 62 decimal places, so the final 1 gets cut off... but we're left with 2^62, which is almost exactly equal to the number you're trying to store.
I'm bad at manufacturing examples, but CERT isn't; you can view an example of what happens with bungled number conversions here. Note that the example is in Java, but C++ uses the same floating point types; additionally, the first example is a conversion between a 4-byte int and a 4-byte float, but this further proves your point (there's less integer information that needs to be stored than there is in your example, yet it still fails).

Confusion about float data type declaration in C++

a complete newbie here. For my school homework, I was given to write a program that displays -
s= 1 + 1/2 + 1/3 + 1/4 ..... + 1/n
Here's what I did -
#include<iostream.h>
#include<conio.h>
void main()
{
clrscr();
int a;
float s=0, n;
cin>>a;
for(n=1;n<=a;n++)
{
s+=1/n;
}
cout<<s;
getch();
}
It perfectly displays what it should. However, in the past I have only written programs which uses int data type. To my understanding, int data type does not contain any decimal place whereas float does. So I don't know much about float yet. Later that night, I was watching some video on YouTube in which he was writing the exact same program but in a little different way. The video was in some foreign language so I couldn't understand it. What he did was declared 'n' as an integer.
int a, n;
float s=0;
instead of
int a
float s=0, n;
But this was not displaying the desired result. So he went ahead and showed two ways to correct it. He made changes in the for loop body -
s+=1.0f/n;
and
s+=1/(float)n;
To my understanding, he declared 'n' a float data type later in the program(Am I right?). So, my question is, both display the same result but is there any difference between the two? As we are declaring 'n' a float, why he has written 1.0f instead of n.f or f.n. I tried it but it gives error. And in the second method, why we can't write 1(float)/n instead of 1/(float)n? As in the first method we have added float suffix with 1. Also, is there a difference between 1.f and 1.0f?
I tried to google my question but couldn't find any answer. Also, another confusion that came to my mind after a few hours is - Why are we even declaring 'n' a float? As per the program, the sum should come out as a real number. So, shouldn't we declare only 's' a float. The more I think the more I confuse my brain. Please help!
Thank You.
The reason is that integer division behaves different than floating point division.
4 / 3 gives you the integer 1. 10 / 3 gives you the integer 3.
However, 4.0f / 3 gives you the float 1.3333..., 10.0f / 3 gives you the float 3.3333...
So if you have:
float f = 4 / 3;
4 / 3 will give you the integer 1, which will then be stored into the float f as 1.0f.
You instead have to make sure either the divisor or the dividend is a float:
float f = 4.0f / 3;
float f = 4 / 3.0f;
If you have two integer variables, then you have to convert one of them to a float first:
int a = ..., b = ...;
float f = (float)a / b;
float f = a / (float)b;
The first is equivalent to something like:
float tmp = a;
float f = tmp / b;
Since n will only ever have an integer value, it makes sense to define it as as int. However doing so means that this won't work as you might expect:
s+=1/n;
In the division operation both operands are integer types, so it performs integer division which means it takes the integer part of the result and throws away any fractional component. So 1/2 would evaluate to 0 because dividing 1 by 2 results in 0.5, and throwing away the fraction results in 0.
This in contrast to floating point division which keeps the fractional component. C will perform floating point division if either operand is a floating point type.
In the case of the above expression, we can force floating point division by performing a typecast on either operand:
s += (float)1/n
Or:
s += 1/(float)n
You can also specify the constant 1 as a floating point constant by giving a decimal component:
s += 1.0/n
Or appending the f suffix:
s += 1.0f/n
The f suffix (as well as the U, L, and LL suffixes) can only be applied to numerical constants, not variables.
What he is doing is something called casting. I'm sure your school will mention it in new lectures. Basically n is set as an integer for the entire program. But since integer and double are similar (both are numbers), the c/c++ language allows you to use them as either as long as you tell the compiler what you want to use it as. You do this by adding parenthesis and the data type ie
(float) n
he declared 'n' a float data type later in the program(Am I right?)
No, he defined (thereby also declared) n an int and later he explicitly converted (casted) it into a float. Both are very different.
both display the same result but is there any difference between the two?
Nope. They're the same in this context. When an arithmetic operator has int and float operands, the former is implicitly converted into the latter and thereby the result will also be a float. He's just shown you two ways to do it. When both the operands are integers, you'd get an integer value as a result which may be incorrect, when proper mathematical division would give you a non-integer quotient. To avoid this, usually one of the operands are made into a floating-point number so that the actual result is closer to the expected result.
why he has written 1.0f instead of n.f or f.n. I tried it but it gives error. [...] Also, is there a difference between 1.f and 1.0f?
This is because the language syntax is defined thus. When you're declaring a floating-point literal, the suffix is to use .f. So 5 would be an int while 5.0f or 5.f is a float; there's no difference when you omit any trailing 0s. However, n.f is syntax error since n is a identifier (variable) name and not a constant number literal.
And in the second method, why we can't write 1(float)/n instead of 1/(float)n?
(float)n is a valid, C-style casting of the int variable n, while 1(float) is just syntax error.
s+=1.0f/n;
and
s+=1/(float)n;
... So, my question is, both display the same result but is there any difference between the two?
Yes.
In both C and C++, when a calculation involves expressions of different types, one or more of those expressions will be "promoted" to the type with greater precision or range. So if you have an expression with signed and unsigned operands, the signed operand will be "promoted" to unsigned. If you have an expression with float and double operands, the float operand will be promoted to double.
Remember that division with two integer operands gives an integer result - 1/2 yields 0, not 0.5. To get a floating point result, at least one of the operands must have a floating point type.
In the case of 1.0f/n, the expression 1.0f has type float1, so the n will be "promoted" from type int to type float.
In the case of 1/(float) n, the expression n is being explicitly cast to type float, so the expression 1 is promoted from type int to float.
Nitpicks:
Unless your compiler documentation explicitly lists void main() as a legal signature for the main function, use int main() instead. From the online C++ standard:
3.6.1 Main function
...
2 An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a declared return type of type int, but otherwise its type is implementation-defined...
Secondly, please format your code - it makes it easier for others to read and debug. Whitespace and indentation are your friends - use them.
1. The constant expression 1.0 with no suffix has type double. The f suffix tells the compiler to treat it as float. 1.0/n would result in a value of type double.

int conversion -- gives me weird numbers

I'm new to the programming world and C++ is already losing me. I had these lines in my program
pennies=(amount-nickels*.05)/.01;
amount is a double, while and nickels are int.
The program returns the right value when pennies is a double but things are a little off (off by 1 most of the time) whenever pennies is an int.
Why is this happening?
This is happening because the value is truncated thus losing the decimal precision.
For integers:
int i;
i = 1.1 //stores 1 in i
i = 1.2 //stores 1 in i
i = 1.3 //stores 1 in i
i = 1.4 //stores 1 in i
i = 1.5 //stores 1 in i
i = 1.6 //stores 1 in i
i = 1.7 //stores 1 in i
i = 1.8 //stores 1 in i
i = 1.9 //stores 1 in i
i = 1.999999 //stores 1 in i
I would suggest you to change your expression to:
pennies=amount*100-nickels*5;
As others have pointed out, the problem is because 0.1 and
0.05 don't have an exact representations in machine floating
point. The simplest solution here is to simply round the
results, instead of truncating:
pennies = round( (amount - nickels * 0.05) / 0.01 );
A better solution in this particular case (where you are dealing
with coins) is simply to use integers everywhere, and do
everything in terms of cents, rather than dollars. This stops
working (or requires some very complex programming) very quickly
however: even things like calculating VAT or sales tax cause
problems. For such cases, there are two possible solutions:
Continue using double, rounding as necessary. This is the
simplest and most general solution. Be aware, however, that
when using it, rounding is done on binary values, and it may
in some cases differ from what you would get with rounding
decimal values. The difference should be small enough that it
won't matter for every day use, but most countries have laws
specifying how such values must be rounded, and those rounding
rules are always specified in decimal. Which means that this
solution cannot be used in cases where legal requirements hold
(e.g calculating sales tax, corporate bookkeeping, etc.).
Use some sort of decimal class. There are a number available
on the network. This will result in slower execution times.
(Typically, who cares. You'll get the results in 100
microseconds, rather than 10. But there are exceptions; e.g.
when doing Monte Carlo simulations.)
Also, you must be aware when large values are involved. For
your personal finances, it's almost certainly irrelevant, but
int does have a maximum value, and there is a point where
double can no longer represent integer values correctly.
Of course, if this is just an exercise to help in learning C++,
just use round or integers, and don't worry too much about the
rest.
And as for your comment "C++ is already losing me": this has
nothing to do with C++ per se. You'd encounter exactly the same
issues in (almost) any programming language.
You compute a float number on the right part of the expression, but then you try to store a double in an int value. When you do this, the fractional part is lost.
pennies=(amount-nickels*.05)/.01;
In the above expression, the numerator and denominator arithmetic occurs in double because of the variable amount(which is double)-Implicit Conversion happens here. At the end if pennies is double the computed result will get stored in pennies, if it is int, fractional part of the computed result will be lost. The intermediate compution will always happens in double, and it doesn't depends upon pennies type anyway.
Example
#include <stdio.h>
int main()
{
int a ;
double c,d=10.55555;
a = c= (d+ 10*.5)/0.5 ;
printf("%f : %d/n",c,a);
return 0;
}
The output is:
31.111100 : 31
Here first 10 is promoted to float then 10*.5 will get evaluated, which will get promoted to double because of addition with a double value, then the denominator also converted to double as numerator is double, hence the compution occurs in double format only.

Converting variable type (or workaround)

The class below is supposed to represent a musical note. I want to be able to store the length of the note (e.g. 1/2 note, 1/4 note, 3/8 note, etc.) using only integers. However, I also want to be able to store the length using a floating point number for the rare case that I deal with notes of irregular lengths.
class note{
string tone;
int length_numerator;
int length_denominator;
public:
set_length(int numerator, int denominator){
length_numerator=numerator;
length_denominator=denominator;
}
set_length(double d){
length_numerator=d; // unfortunately truncates everything past decimal point
length_denominator=1;
}
}
The reason it is important for me to be able to use integers rather than doubles to store the length is that in my past experience with floating point numbers, sometimes the values are unexpectedly inaccurate. For example, a number that is supposed to be 16 occasionally gets mysteriously stored as 16.0000000001 or 15.99999999999 (usually after enduring some operations) with floating point, and this could cause problems when testing for equality (because 16!=15.99999999999).
Is it possible to convert a variable from int to double (the variable, not just its value)? If not, then what else can I do to be able to store the note's length using either an integer or a double, depending on the what I need the type to be?
If your only problem is comparing floats for equality, then I'd say to use floats, but read "Comparing floating point numbers" / Bruce Dawson first. It's not long, and it explains how to compare two floating numbers correctly (by checking the absolute and relative difference).
When you have more time, you should also look at "What Every Computer Scientist Should Know About Floating Point Arithmetic" to understand why 16 occasionally gets "mysteriously" stored as 16.0000000001 or 15.99999999999.
Attempts to use integers for rational numbers (or for fixed point arithmetic) are rarely as simple as they look.
I see several possible solutions: the first is just to use double. It's
true that extended computations may result in inaccurate results, but in
this case, your divisors are normally powers of 2, which will give exact
results (at least on all of the machines I've seen); you only risk
running into problems when dividing by some unusual value (which is the
case where you'll have to use double anyway).
You could also scale the results, e.g. representing the notes as
multiples of, say 64th notes. This will mean that most values will be
small integers, which are guaranteed exact in double (again, at least
in the usual representations). A number that is supposed to be 16 does
not get stored as 16.000000001 or 15.99999999 (but a number that is
supposed to be .16 might get stored as .1600000001 or .1599999999).
Before the appearance of long long, decimal arithmetic classes often
used double as a 52 bit integral type, ensuring at each step that the
actual value was exactly an integer. (Only division might cause a problem.)
Or you could use some sort of class representing rational numbers.
(Boost has one, for example, and I'm sure there are others.) This would
allow any strange values (5th notes, anyone?) to remain exact; it could
also be advantageous for human readable output, e.g. you could test the
denominator, and then output something like "3 quarter notes", or the
like. Even something like "a 3/4 note" would be more readable to a
musician than "a .75 note".
It is not possible to convert a variable from int to double, it is possible to convert a value from int to double. I'm not completely certain which you are asking for but maybe you are looking for a union
union DoubleOrInt
{
double d;
int i;
};
DoubleOrInt length_numerator;
DoubleOrInt length_denominator;
Then you can write
set_length(int numerator, int denominator){
length_numerator.i=numerator;
length_denominator.i=denominator;
}
set_length(double d){
length_numerator.d=d;
length_denominator.d=1.0;
}
The problem with this approach is that you absolutely must keep track of whether you are currently storing ints or doubles in your unions. Bad things will happen if you store an int and then try to access it as a double. Preferrably you would do this inside your class.
This is normal behavior for floating point variables. They are always rounded and the last digits may change valued depending on the operations you do. I suggest reading on floating points somewhere (e.g. http://floating-point-gui.de/) - especially about comparing fp values.
I normally subtract them, take the absolute value and compare this against an epsilon, e.g. if (abs(x-y)
Given you have a set_length(double d), my guess is that you actually need doubles. Note that the conversion from double to a fraction of integer is fragile and complexe, and will most probably not solve your equality problems (is 0.24999999 equal to 1/4 ?). It would be better for you to either choose to always use fractions, or always doubles. Then, just learn how to use them. I must say, for music, it make sense to have fractions as it is even how notes are being described.
If it were me, I would just use an enum. To turn something into a note would be pretty simple using this system also. Here's a way you could do it:
class Note {
public:
enum Type {
// In this case, 16 represents a whole note, but it could be larger
// if demisemiquavers were used or something.
Semiquaver = 1,
Quaver = 2,
Crotchet = 4,
Minim = 8,
Semibreve = 16
};
static float GetNoteLength(const Type &note)
{ return static_cast<float>(note)/16.0f; }
static float TieNotes(const Type &note1, const Type &note2)
{ return GetNoteLength(note1)+GetNoteLength(note2); }
};
int main()
{
// Make a semiquaver
Note::Type sq = Note::Semiquaver;
// Make a quaver
Note::Type q = Note::Quaver;
// Dot it with the semiquaver from before
float dottedQuaver = Note::TieNotes(sq, q);
std::cout << "Semiquaver is equivalent to: " << Note::GetNoteLength(sq) << " beats\n";
std::cout << "Dotted quaver is equivalent to: " << dottedQuaver << " beats\n";
return 0;
}
Those 'Irregular' notes you speak of can be retrieved using TieNotes

C++ float to int

Maybe, it's very simple question but I couldn't get the answer. I've been searching quite a while ( now Google think that I'm sending automated queries http://twitter.com/michaelsync/status/17177278608 ) ..
int n = 4.35 *100;
cout << n;
Why does the output become "434" instead of "435"? 4.35 * 100 = 435 which is a integer value and this should be assignable to the integer variable "n", right?
OR Does the C++ compiler cast 4.35 to integer before multiplying? I think it won't. Why does the compiler automatically change 4.35 to 4.34 which is still a float??
Thanks.
What Every Computer Scientist Should Know About Floating-Point Arithmetic
That's really just a starting point, sadly, as then languages introduce their own foibles as to when they do type conversions, etc. In this case you've merely created a situation where the constant 4.35 can't be represented precisely, and thus 4.35*100 is more like 434.9999999999, and the cast to int does trunc, not round.
If you run this statement:
cout << 4.35
Dollars to donuts you get something approximately like 4.3499998821 because 4.35 isn't exactly representable in a float.
When the compiler casts a float to an int it truncates.
To get the behavior your expect, try:
int n = floor((4.35 * 100.0) + 0.5);
(The trickyness with floor is because C++ doesn't have a native round() function)
The internal representation of 4.35 ends up being 4.349999999 or similar. Multiplying by 100 shifts the decimal, and the .9999 is dropped off (truncated) when converting to int.
Edit: Was looking for the link Nick posted. :)
Floating point numbers don't work that way. Many (most, technically an infinite number of...) values cannot be stored or manipulated precisely as floating point. 4.35 would seem to be one of them. It's getting stored as something that's actually below 4.35, hence your result.
When a float is converted to an int the fractional part is truncated, the conversion doesn't take the nearest int to the float in value.
4.35 can't be exactly represented as a float, the nearest representable number is (we can deduce) very slightly less that 4.35, i.e. 4.34999... , so when multiplied by 100 you get 434.999...
If you want to convert a positive float to the nearest int you should add 0.5 before converting to int.
E.g.
int n = (4.35 * 100) + 0.5;
cout << n;